Showing preview only (896K chars total). Download the full file or copy to clipboard to get everything.
Repository: travisdowns/avx-turbo
Branch: master
Commit: 9cfe8bf30896
Files: 33
Total size: 870.3 KB
Directory structure:
gitextract_u04fsbhh/
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── Makefile
├── README.md
├── args.hxx
├── asm-methods.asm
├── atomic.h
├── avx-turbo.cpp
├── check-uarch.sh
├── config.mk
├── cpu.c
├── cpu.h
├── cpuid.cpp
├── cpuid.hpp
├── exact-int.h
├── msr-access.c
├── msr-access.h
├── nasm-2.13.03/
│ ├── LICENSE
│ ├── NOTE
│ └── nasm
├── nasm-utils-helper.c
├── nasm-utils-inc.asm
├── once.h
├── stats.hpp
├── table.hpp
├── test/
│ ├── catch.hpp
│ ├── unit-test-main.cpp
│ └── unit-test.cpp
├── tsc-support.cpp
├── tsc-support.hpp
└── util.hpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/build.yml
================================================
name: build
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
cpp_compiler: [g++, g++-7, g++-8, g++-9, clang++, clang++-9]
include:
- c_compiler: gcc
- cpp_compiler: g++-7
c_compiler: gcc-7
- cpp_compiler: g++-8
c_compiler: gcc-8
- cpp_compiler: g++-9
c_compiler: gcc-9
- cpp_compiler: clang++
c_compiler: clang
- cpp_compiler: clang++-9
c_compiler: clang-9
steps:
- name: Install C Compiler
if: ${{ startsWith(matrix.c_compiler, 'gcc-') || startsWith(matrix.c_compiler, 'clang-') }}
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.c_compiler }}
- name: Install C++ Compiler
if: ${{ startsWith(matrix.cpp_compiler, 'g++-') || startsWith(matrix.cpp_compiler, 'clang++-') }}
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.cpp_compiler }}
- uses: actions/checkout@v2
- run: lscpu
- run: make -j2 CC=${{ matrix.c_compiler }} CXX=${{ matrix.cpp_compiler }}
- run: ./unit-test
- run: ./avx-turbo --no-pin --max-threads 2
================================================
FILE: .gitignore
================================================
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
avx-turbo
unit-test
# Eclipse CDT artifacts
.cproject
.project
.settings
# nasm listing file
*.list
# libpfm4 directory
libpfm-4*/*
# core files
/core*
/vgcore*
# perf files
/perf.*
/tmp/*
dummy.rebuild
# local make config file
local.mk
================================================
FILE: .travis.yml
================================================
dist: xenial
language: cpp
sudo: false
branches:
except:
- /^(wip\/)?(appveyor|msvc|mingw|windows)(\-.+)?$/
addons:
apt:
sources: &default_sources
- ubuntu-toolchain-r-test
# the anchors element doesn't do anything but itself except define some anchors to be used later as aliases
anchors:
- &unit_command ./unit-test
- &uarch_command ./uarch-bench --test-tag=~slow
matrix:
include:
# clang-5.0 is the default installed on travis VMs
- compiler: clang-default
env: TRUE_CC=clang TRUE_CXX=clang++ CXXFLAGS=-stdlib=libc++
addons:
apt:
sources:
- *default_sources
- llvm-toolchain-trusty-5.0
packages:
- libc++abi1
- libc++1
- compiler: gcc-4.9
env: TRUE_CC=gcc-4.9 TRUE_CXX=g++-4.9
addons:
apt:
sources:
- *default_sources
packages:
- gcc-4.9
- g++-4.9
- compiler: gcc-6
env: TRUE_CC=gcc-6 TRUE_CXX=g++-6
addons:
apt:
sources:
- *default_sources
packages:
- gcc-6
- g++-6
- compiler: clang-6.0
env: TRUE_CC=clang-6.0 TRUE_CXX=clang++-6.0
addons:
apt:
sources:
- *default_sources
- llvm-toolchain-xenial-6.0
packages:
- clang-6.0
- clang++-6.0
before_install:
# Travis will set CC and CXX after the env commands specified in the matrix are run, overwriting whatever
# we've specified there, so we need to reset them here. See also https://github.com/travis-ci/travis-ci/issues/6633 .
- CC="${TRUE_CC:-$CC}"
- CXX="${TRUE_CXX:-$CXX}"
script:
- set -e && echo "CC is ${CC}, CXX is ${CXX}" && ${CC} --version && ${CXX} --version
- make
- ./avx-turbo --no-pin --max-threads 2
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 travisdowns
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, 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
AUTHORS OR 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.
================================================
FILE: Makefile
================================================
include config.mk
# rebuild when makefile changes
-include dummy.rebuild
.PHONY: all clean
ASM_FLAGS ?= -DNASM_ENABLE_DEBUG=$(NASM_DEBUG) -w+all -l x86_methods.list
ifneq ($(CPU_ARCH),)
ARCH_FLAGS := -march=$(CPU_ARCH)
endif
O_LEVEL ?= -O2
COMMON_FLAGS := -MMD -Wall -Wextra -Wundef $(ARCH_FLAGS) -g $(O_LEVEL)
CPPFLAGS := $(COMMON_FLAGS)
CFLAGS := $(COMMON_FLAGS)
SRC_FILES := $(wildcard *.cpp) $(wildcard *.c)
OBJECTS := $(SRC_FILES:.cpp=.o) asm-methods.o
OBJECTS := $(OBJECTS:.c=.o)
DEPFILES = $(OBJECTS:.o=.d)
# $(info OBJECTS=$(OBJECTS))
VPATH = test
###########
# Targets #
###########
all: avx-turbo unit-test
-include $(DEPFILES) unit-test.d
clean:
rm -f *.d *.o avx-turbo
dist-clean: clean $(CLEAN_TARGETS)
unit-test: unit-test.o unit-test-main.o cpuid.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) -std=c++11 $^ -o $@
avx-turbo: $(OBJECTS)
$(CXX) $(OBJECTS) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) -std=c++11 -lpthread -o $@
%.o : %.c
$(CC) $(CFLAGS) -c -std=c11 -o $@ $<
%.o : %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -std=c++11 -o $@ $<
%.o: %.asm nasm-utils-inc.asm
$(ASM) $(ASM_FLAGS) -f elf64 $<
LOCAL_MK = $(wildcard local.mk)
# https://stackoverflow.com/a/3892826/149138
dummy.rebuild: Makefile config.mk $(LOCAL_MK)
touch $@
$(MAKE) -s clean
================================================
FILE: README.md
================================================
# avx-turbo
Test the non-AVX, AVX2 and AVX-512 speeds for various types of CPU intensive loops with varying scalar and SIMD instructions, across different active core counts.
Currently it is **Linux only** (it does run on WSL and WSL2 on Windows), but the basic testing mechanism could be ported to OSX and Windows as well (help welcome).
# CI Status
**Build:** [](https://github.com/travisdowns/avx-turbo/actions?query=workflow%3Abuild+branch%3Amaster)
# build
make
# msr kernel module
You should load the `msr` kernel module if it is not already loaded. This is as simple as:
modprobe msr
Or as complex as (if you want nice messages about what happened):
lsmod | grep -q msr && echo "MSR already loaded" || { echo "Loading MSR module"; sudo modprobe msr ; }
# run
You get the most info running as root (since we can read various MSRs to calculate the frequency directly):
sudo ./avx-turbo
You can also run it without root, but you only get the "Mops" reading (but this can be read directly as frequency
for the 1-latency tests).
## spec-based tests
The default behavior for ./avx-turbo is to run tests with various thread counts, but with the same test on each thread. For example, the `avx256_fma` test means that the same FMA-using test code will be run on _each_ test thread.
An alternate approach is availe with so-called _spec-based_ tests. This lets you specificy exactly what each thread in a test will run. The general form of a specification is: `test1/thead-count1[,test2/thread-count2[,...]]`. For example,
if you run `sudo ./avx-turbo --spec avx256_fma/1,scalar_iadd/3` you'll get one copy of `avx256_fma` and three copies of `scalar_iadd` running in parallel.
This mode is useful to testing that happens when not all cores are doing the same thing.
# help
Try:
./avx-turbo --help
for a summary of some options something like this:
```
./avx-turbo {OPTIONS}
avx-turbo: Determine AVX2 and AVX-512 downclocking behavior
OPTIONS:
-h, --help Display this help menu
--force-tsc-calibrate Force manual TSC calibration loop, even
if cpuid TSC Hz is available
--no-pin Don't try to pin threads to CPU - gives
worse results but works around affinity
issues on TravisCI
--verbose Output more info
--no-barrier Don't sync up threads before each test
(no real purpose)
--list List the available tests and their
descriptions
--allow-hyperthreads By default we try to filter down the
available cpus to include only physical
cores, but with this option we'll use
all logical cores meaning you'll run two
tests on cores with hyperthreading
--test=[TEST-ID] Run only the specified test (by ID)
--spec=[SPEC] Run a specific type of test specified by
a specification string
--iters=[ITERS] Run the test loop ITERS times (default
100000)
--min-threads=[MIN] The minimum number of threads to use
--max-threads=[MAX] The maximum number of threads to use
--warmup-ms=[MILLISECONDS] Warmup milliseconds for each thread
after pinning (default 100)
```
# output
The output looks like this:
```
Running as root : [YES]
CPU supports AVX2 : [YES]
CPU supports AVX-512: [NO ]
cpuid = eax = 2, ebx = 216, ecx = 0, edx = 0
cpu: family = 6, model = 94, stepping = 3
tsc_freq = 2592.0 MHz (from cpuid leaf 0x15)
Will test up to 4 CPUs
============================== Threads: 1 ==============================
ID | Description | Mops | A/M-ratio | A/M-MHz | M/tsc-ratio
scalar_iadd | Scalar integer adds | 2594 | 1.00 | 2592 | 1.00
avx128_iadd | 128-bit integer adds | 2594 | 1.00 | 2592 | 1.00
avx128_imul | 128-bit integer muls | 519 | 1.00 | 2592 | 1.00
avx128_fma | 128-bit 64-bit FMAs | 649 | 1.00 | 2592 | 1.00
avx256_iadd | 256-bit integer adds | 2594 | 1.00 | 2592 | 1.00
avx256_imul | 256-bit integer muls | 519 | 1.00 | 2592 | 1.00
avx256_fma | 256-bit serial DP FMAs | 648 | 1.00 | 2592 | 1.00
avx256_fma_t | 256-bit parallel DP FMAs | 5189 | 1.00 | 2592 | 1.00
=========================================================================
============================== Threads: 2 ==============================
ID | Description | Mops | A/M-ratio | A/M-MHz | M/tsc-ratio
scalar_iadd | Scalar integer adds | 2593, 2593 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx128_iadd | 128-bit integer adds | 2594, 2594 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx128_imul | 128-bit integer muls | 519, 519 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx128_fma | 128-bit 64-bit FMAs | 648, 649 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx256_iadd | 256-bit integer adds | 2594, 2594 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx256_imul | 256-bit integer muls | 519, 519 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx256_fma | 256-bit serial DP FMAs | 648, 648 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
avx256_fma_t | 256-bit parallel DP FMAs | 5188, 5189 | 1.00, 1.00 | 2592, 2592 | 1.00, 1.00
=========================================================================
============================== Threads: 3 ==============================
ID | Description | Mops | A/M-ratio | A/M-MHz | M/tsc-ratio
scalar_iadd | Scalar integer adds | 2594, 2594, 2594 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx128_iadd | 128-bit integer adds | 2594, 2594, 2594 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx128_imul | 128-bit integer muls | 519, 519, 519 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx128_fma | 128-bit 64-bit FMAs | 649, 648, 648 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx256_iadd | 256-bit integer adds | 2594, 2594, 2594 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx256_imul | 256-bit integer muls | 519, 519, 519 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx256_fma | 256-bit serial DP FMAs | 649, 648, 649 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
avx256_fma_t | 256-bit parallel DP FMAs | 5190, 5189, 5190 | 1.00, 1.00, 1.00 | 2592, 2592, 2592 | 1.00, 1.00, 1.00
=========================================================================
============================== Threads: 4 ==============================
ID | Description | Mops | A/M-ratio | A/M-MHz | M/tsc-ratio
scalar_iadd | Scalar integer adds | 2594, 2594, 2594, 2594 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx128_iadd | 128-bit integer adds | 2593, 2594, 2594, 2594 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx128_imul | 128-bit integer muls | 519, 519, 519, 519 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx128_fma | 128-bit 64-bit FMAs | 648, 648, 649, 648 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx256_iadd | 256-bit integer adds | 2594, 2594, 2594, 2594 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx256_imul | 256-bit integer muls | 519, 519, 519, 519 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx256_fma | 256-bit serial DP FMAs | 648, 648, 648, 648 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
avx256_fma_t | 256-bit parallel DP FMAs | 5189, 5189, 5189, 5189 | 1.00, 1.00, 1.00, 1.00 | 2592, 2592, 2592, 2592 | 1.00, 1.00, 1.00, 1.00
=========================================================================
```
The headings are:
- `ID` The ID for the test, which you can use with the `--test` argument to only run a specific test (handy when you want to focus on one test to read the frequency externally, e.g., via `perf`).
- `Description` Yes, it's a description.
- `Mops` Million operations per second. Every test runs a loop of the same type of instruction and this is how many millions of those instructions were executed per second. This is handy since this value corresponds exactly to frequency in MHz for tests with serially dependent 1-latency instructions, which here are all the "integer adds" tests.
- `A/M` This is the ratio of the `APERF` and `MPERF` ratios exposed in an MSR. For details, see the [Intel SDM Vol 3](https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-3a-3b-3c-and-3d-system-programming-guide), but basically APERF is a free running counter of actual cycles (i.e., varying with the CPU frequency), while MPERF counts at a constant rate, usually the processor's nominal frequency. A ratio of 1.0 therefore means that the CPU was is running, on average, at the nominal frequency during the test (I had turbo off, that's why you see 1.00 everywhere). Lower than 1 means lower than nominal frequencies (e.g., due to running heavy AVX code).
- `A/M-MHz` This is the measured frequency over the duration of the test, based on the `APERF` and `MPERF` ratio described above, multiplied by the base (TSC) frequency. Note that this only counts "non-halted" periods, so if the CPU was running at 1000 MHz half the time but halted the other half of the time (due to a frequency transition), you'd see 1000 MHz here, not 500 MHz.
- `M/tsc-ratio` This shows the ration of the `MPERF` register to the TSC (time stamp counter) over the duration of the test. These counters count at the same rate, except that `MPERF` only counts "unhalted" cycles, while the TSC counts all cycles, so this ratio gives you an indication of the "lost" cycles due to halt events. A big source of halt events is frequency transitions in the turbo range: on my Skylake client CPU, any time another core starts up, the allowed turbo ratio changes, so the CPU halts for perhaps 20,000 cycles, so with moderate activity I often see ratios of 0.9 which means that 10% of the time my CPU is doing nothing. To get a "true" frequency, you should multiply this ratio by the `A/M-MHz` column, which would be the actual average frequency, counting halted periods as zero.
================================================
FILE: args.hxx
================================================
/* Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel
* Belikov
*
* 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, 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
* AUTHORS OR 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.
*/
/** \file args.hxx
* \brief this single-header lets you use all of the args functionality
*
* The important stuff is done inside the args namespace
*/
#ifndef ARGS_HXX
#define ARGS_HXX
#include <algorithm>
#include <exception>
#include <functional>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <type_traits>
#ifdef ARGS_TESTNAMESPACE
namespace argstest
{
#else
/** \namespace args
* \brief contains all the functionality of the args library
*/
namespace args
{
#endif
/** Getter to grab the value from the argument type.
*
* If the Get() function of the type returns a reference, so does this, and
* the value will be modifiable.
*/
template <typename Option>
auto get(Option &option_) -> decltype(option_.Get())
{
return option_.Get();
}
/** (INTERNAL) Count UTF-8 glyphs
*
* This is not reliable, and will fail for combinatory glyphs, but it's
* good enough here for now.
*
* \param string The string to count glyphs from
* \return The UTF-8 glyphs in the string
*/
inline std::string::size_type Glyphs(const std::string &string_)
{
std::string::size_type length = 0;
for (const char c: string_)
{
if ((c & 0xc0) != 0x80)
{
++length;
}
}
return length;
}
/** (INTERNAL) Wrap a string into a vector of lines
*
* This is quick and hacky, but works well enough. You can specify a
* different width for the first line
*
* \param width The width of the body
* \param the width of the first line, defaults to the width of the body
* \return the vector of lines
*/
inline std::vector<std::string> Wrap(const std::string &in, const std::string::size_type width, std::string::size_type firstlinewidth = 0)
{
// Preserve existing line breaks
const auto newlineloc = in.find('\n');
if (newlineloc != in.npos)
{
auto first = Wrap(std::string(in, 0, newlineloc), width);
auto second = Wrap(std::string(in, newlineloc + 1), width);
first.insert(
std::end(first),
std::make_move_iterator(std::begin(second)),
std::make_move_iterator(std::end(second)));
return first;
}
if (firstlinewidth == 0)
{
firstlinewidth = width;
}
auto currentwidth = firstlinewidth;
std::istringstream stream(in);
std::vector<std::string> output;
std::ostringstream line;
std::string::size_type linesize = 0;
while (stream)
{
std::string item;
stream >> item;
auto itemsize = Glyphs(item);
if ((linesize + 1 + itemsize) > currentwidth)
{
if (linesize > 0)
{
output.push_back(line.str());
line.str(std::string());
linesize = 0;
currentwidth = width;
}
}
if (itemsize > 0)
{
if (linesize)
{
++linesize;
line << " ";
}
line << item;
linesize += itemsize;
}
}
if (linesize > 0)
{
output.push_back(line.str());
}
return output;
}
#ifdef ARGS_NOEXCEPT
/// Error class, for when ARGS_NOEXCEPT is defined
enum class Error
{
None,
Usage,
Parse,
Validation,
Required,
Map,
Extra,
Help
};
#else
/** Base error class
*/
class Error : public std::runtime_error
{
public:
Error(const std::string &problem) : std::runtime_error(problem) {}
virtual ~Error() {};
};
/** Errors that occur during usage
*/
class UsageError : public Error
{
public:
UsageError(const std::string &problem) : Error(problem) {}
virtual ~UsageError() {};
};
/** Errors that occur during regular parsing
*/
class ParseError : public Error
{
public:
ParseError(const std::string &problem) : Error(problem) {}
virtual ~ParseError() {};
};
/** Errors that are detected from group validation after parsing finishes
*/
class ValidationError : public Error
{
public:
ValidationError(const std::string &problem) : Error(problem) {}
virtual ~ValidationError() {};
};
/** Errors that when a required flag is omitted
*/
class RequiredError : public ValidationError
{
public:
RequiredError(const std::string &problem) : ValidationError(problem) {}
virtual ~RequiredError() {};
};
/** Errors in map lookups
*/
class MapError : public ParseError
{
public:
MapError(const std::string &problem) : ParseError(problem) {}
virtual ~MapError() {};
};
/** Error that occurs when a singular flag is specified multiple times
*/
class ExtraError : public ParseError
{
public:
ExtraError(const std::string &problem) : ParseError(problem) {}
virtual ~ExtraError() {};
};
/** An exception that indicates that the user has requested help
*/
class Help : public Error
{
public:
Help(const std::string &flag) : Error(flag) {}
virtual ~Help() {};
};
#endif
/** A simple unified option type for unified initializer lists for the Matcher class.
*/
struct EitherFlag
{
const bool isShort;
const char shortFlag;
const std::string longFlag;
EitherFlag(const std::string &flag) : isShort(false), shortFlag(), longFlag(flag) {}
EitherFlag(const char *flag) : isShort(false), shortFlag(), longFlag(flag) {}
EitherFlag(const char flag) : isShort(true), shortFlag(flag), longFlag() {}
/** Get just the long flags from an initializer list of EitherFlags
*/
static std::unordered_set<std::string> GetLong(std::initializer_list<EitherFlag> flags)
{
std::unordered_set<std::string> longFlags;
for (const EitherFlag &flag: flags)
{
if (!flag.isShort)
{
longFlags.insert(flag.longFlag);
}
}
return longFlags;
}
/** Get just the short flags from an initializer list of EitherFlags
*/
static std::unordered_set<char> GetShort(std::initializer_list<EitherFlag> flags)
{
std::unordered_set<char> shortFlags;
for (const EitherFlag &flag: flags)
{
if (flag.isShort)
{
shortFlags.insert(flag.shortFlag);
}
}
return shortFlags;
}
};
/** A class of "matchers", specifying short and flags that can possibly be
* matched.
*
* This is supposed to be constructed and then passed in, not used directly
* from user code.
*/
class Matcher
{
private:
const std::unordered_set<char> shortFlags;
const std::unordered_set<std::string> longFlags;
public:
/** Specify short and long flags separately as iterators
*
* ex: `args::Matcher(shortFlags.begin(), shortFlags.end(), longFlags.begin(), longFlags.end())`
*/
template <typename ShortIt, typename LongIt>
Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd) :
shortFlags(shortFlagsStart, shortFlagsEnd),
longFlags(longFlagsStart, longFlagsEnd)
{}
/** Specify short and long flags separately as iterables
*
* ex: `args::Matcher(shortFlags, longFlags)`
*/
template <typename Short, typename Long>
Matcher(Short &&shortIn, Long &&longIn) :
shortFlags(std::begin(shortIn), std::end(shortIn)), longFlags(std::begin(longIn), std::end(longIn))
{}
/** Specify a mixed single initializer-list of both short and long flags
*
* This is the fancy one. It takes a single initializer list of
* any number of any mixed kinds of flags. Chars are
* automatically interpreted as short flags, and strings are
* automatically interpreted as long flags:
*
* args::Matcher{'a'}
* args::Matcher{"foo"}
* args::Matcher{'h', "help"}
* args::Matcher{"foo", 'f', 'F', "FoO"}
*/
Matcher(std::initializer_list<EitherFlag> in) :
shortFlags(EitherFlag::GetShort(in)), longFlags(EitherFlag::GetLong(in)) {}
Matcher(Matcher &&other) : shortFlags(std::move(other.shortFlags)), longFlags(std::move(other.longFlags))
{}
~Matcher() {}
/** (INTERNAL) Check if there is a match of a short flag
*/
bool Match(const char flag) const
{
return shortFlags.find(flag) != shortFlags.end();
}
/** (INTERNAL) Check if there is a match of a long flag
*/
bool Match(const std::string &flag) const
{
return longFlags.find(flag) != longFlags.end();
}
/** (INTERNAL) Get all flag strings as a vector, with the prefixes embedded
*/
std::vector<std::string> GetFlagStrings(const std::string &shortPrefix, const std::string &longPrefix) const
{
std::vector<std::string> flagStrings;
flagStrings.reserve(shortFlags.size() + longFlags.size());
for (const char flag: shortFlags)
{
flagStrings.emplace_back(shortPrefix + std::string(1, flag));
}
for (const std::string &flag: longFlags)
{
flagStrings.emplace_back(longPrefix + flag);
}
return flagStrings;
}
/** (INTERNAL) Get all flag strings as a vector, with the prefixes and names embedded
*/
std::vector<std::string> GetFlagStrings(const std::string &shortPrefix, const std::string &longPrefix, const std::string &name, const std::string &shortSeparator, const std::string longSeparator) const
{
const std::string bracedname(std::string("[") + name + "]");
std::vector<std::string> flagStrings;
flagStrings.reserve(shortFlags.size() + longFlags.size());
for (const char flag: shortFlags)
{
flagStrings.emplace_back(shortPrefix + std::string(1, flag) + shortSeparator + bracedname);
}
for (const std::string &flag: longFlags)
{
flagStrings.emplace_back(longPrefix + flag + longSeparator + bracedname);
}
return flagStrings;
}
};
enum class Options
{
/** Default options.
*/
None = 0x0,
/** Flag can't be passed multiple times.
*/
Single = 0x01,
/** Flag can't be omitted.
*/
Required = 0x02,
/** Flag is excluded from help output.
*/
Hidden = 0x04,
};
inline Options operator | (Options lhs, Options rhs)
{
return static_cast<Options>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
inline Options operator & (Options lhs, Options rhs)
{
return static_cast<Options>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
/** Base class for all match types
*/
class Base
{
private:
const Options options;
protected:
bool matched;
const std::string help;
#ifdef ARGS_NOEXCEPT
/// Only for ARGS_NOEXCEPT
Error error;
#endif
public:
Base(const std::string &help_, Options options_ = {}) : options(options_), matched(false), help(help_) {}
virtual ~Base() {}
Options GetOptions() const noexcept
{
return options;
}
virtual bool Matched() const noexcept
{
return matched;
}
virtual void Validate(const std::string &, const std::string &)
{
}
operator bool() const noexcept
{
return Matched();
}
virtual std::tuple<std::string, std::string> GetDescription(const std::string &, const std::string &, const std::string &, const std::string &) const
{
std::tuple<std::string, std::string> description;
std::get<1>(description) = help;
return description;
}
virtual void Reset() noexcept
{
matched = false;
#ifdef ARGS_NOEXCEPT
error = Error::None;
#endif
}
#ifdef ARGS_NOEXCEPT
/// Only for ARGS_NOEXCEPT
virtual Error GetError() const
{
return error;
}
#endif
};
/** Base class for all match types that have a name
*/
class NamedBase : public Base
{
protected:
const std::string name;
bool kickout;
public:
NamedBase(const std::string &name_, const std::string &help_, Options options_ = {}) : Base(help_, options_), name(name_), kickout(false) {}
virtual ~NamedBase() {}
virtual std::tuple<std::string, std::string> GetDescription(const std::string &, const std::string &, const std::string &, const std::string &) const override
{
std::tuple<std::string, std::string> description;
std::get<0>(description) = Name();
std::get<1>(description) = help;
return description;
}
virtual std::string Name() const
{
return name;
}
/// Sets a kick-out value for building subparsers
void KickOut(bool kickout_) noexcept
{
this->kickout = kickout_;
}
/// Gets the kick-out value for building subparsers
bool KickOut() const noexcept
{
return kickout;
}
};
struct Nargs
{
const size_t min;
const size_t max;
Nargs(size_t min_, size_t max_) : min(min_), max(max_)
{
#ifndef ARGS_NOEXCEPT
if (max < min)
{
throw std::invalid_argument("Nargs: max > min");
}
#endif
}
Nargs(size_t num_) : min(num_), max(num_)
{
}
};
/** Base class for all flag options
*/
class FlagBase : public NamedBase
{
protected:
const Matcher matcher;
public:
FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : NamedBase(name_, help_, extraError_ ? Options::Single : Options()), matcher(std::move(matcher_)) {}
FlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : NamedBase(name_, help_, options_), matcher(std::move(matcher_)) {}
virtual ~FlagBase() {}
virtual FlagBase *Match(const std::string &flag)
{
if (matcher.Match(flag))
{
if ((GetOptions() & Options::Single) != Options::None && matched)
{
#ifdef ARGS_NOEXCEPT
error = Error::Extra;
#else
std::ostringstream problem;
problem << "Flag '" << flag << "' was passed multiple times, but is only allowed to be passed once";
throw ExtraError(problem.str());
#endif
}
matched = true;
return this;
}
return nullptr;
}
virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) override
{
if (!Matched() && (GetOptions() & Options::Required) != Options::None)
{
#ifdef ARGS_NOEXCEPT
error = Error::Required;
#else
std::ostringstream problem;
problem << "Flag '" << matcher.GetFlagStrings(shortPrefix, longPrefix).at(0) << "' is required";
throw RequiredError(problem.str());
#endif
}
}
virtual FlagBase *Match(const char flag)
{
if (matcher.Match(flag))
{
if ((GetOptions() & Options::Single) != Options::None && matched)
{
#ifdef ARGS_NOEXCEPT
error = Error::Extra;
#else
std::ostringstream problem;
problem << "Flag '" << flag << "' was passed multiple times, but is only allowed to be passed once";
throw ExtraError(problem.str());
#endif
}
matched = true;
return this;
}
return nullptr;
}
virtual std::tuple<std::string, std::string> GetDescription(const std::string &shortPrefix, const std::string &longPrefix, const std::string &, const std::string &) const override
{
std::tuple<std::string, std::string> description;
const auto flagStrings = matcher.GetFlagStrings(shortPrefix, longPrefix);
std::ostringstream flagstream;
for (auto it = std::begin(flagStrings); it != std::end(flagStrings); ++it)
{
if (it != std::begin(flagStrings))
{
flagstream << ", ";
}
flagstream << *it;
}
std::get<0>(description) = flagstream.str();
std::get<1>(description) = help;
return description;
}
/** Defines how many values can be consumed by this option.
*
* \return closed interval [min, max]
*/
virtual Nargs NumberOfArguments() const noexcept = 0;
/** Parse values of this option.
*
* \param value Vector of values. It's size must be in NumberOfArguments() interval.
*/
virtual void ParseValue(const std::vector<std::string> &value) = 0;
};
/** Base class for value-accepting flag options
*/
class ValueFlagBase : public FlagBase
{
public:
ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false) : FlagBase(name_, help_, std::move(matcher_), extraError_) {}
ValueFlagBase(const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_) : FlagBase(name_, help_, std::move(matcher_), options_) {}
virtual ~ValueFlagBase() {}
virtual std::tuple<std::string, std::string> GetDescription(const std::string &shortPrefix, const std::string &longPrefix, const std::string &shortSeparator, const std::string &longSeparator) const override
{
std::tuple<std::string, std::string> description;
const auto flagStrings = matcher.GetFlagStrings(shortPrefix, longPrefix, Name(), shortSeparator, longSeparator);
std::ostringstream flagstream;
for (auto it = std::begin(flagStrings); it != std::end(flagStrings); ++it)
{
if (it != std::begin(flagStrings))
{
flagstream << ", ";
}
flagstream << *it;
}
std::get<0>(description) = flagstream.str();
std::get<1>(description) = help;
return description;
}
virtual Nargs NumberOfArguments() const noexcept override
{
return 1;
}
};
/** Base class for positional options
*/
class PositionalBase : public NamedBase
{
protected:
bool ready;
public:
PositionalBase(const std::string &name_, const std::string &help_, Options options_ = Options::None) : NamedBase(name_, help_, options_), ready(true) {}
virtual ~PositionalBase() {}
bool Ready()
{
return ready;
}
virtual void ParseValue(const std::string &value_) = 0;
virtual void Reset() noexcept override
{
matched = false;
ready = true;
#ifdef ARGS_NOEXCEPT
error = Error::None;
#endif
}
virtual void Validate(const std::string &, const std::string &) override
{
if ((GetOptions() & Options::Required) != Options::None && !Matched())
{
#ifdef ARGS_NOEXCEPT
error = Error::Required;
#else
std::ostringstream problem;
problem << "Option '" << Name() << "' is required";
throw RequiredError(problem.str());
#endif
}
}
};
/** Class for all kinds of validating groups, including ArgumentParser
*/
class Group : public Base
{
private:
std::vector<Base*> children;
std::function<bool(const Group &)> validator;
public:
/** Default validators
*/
struct Validators
{
static bool Xor(const Group &group)
{
return group.MatchedChildren() == 1;
}
static bool AtLeastOne(const Group &group)
{
return group.MatchedChildren() >= 1;
}
static bool AtMostOne(const Group &group)
{
return group.MatchedChildren() <= 1;
}
static bool All(const Group &group)
{
return group.Children().size() == group.MatchedChildren();
}
static bool AllOrNone(const Group &group)
{
return (All(group) || None(group));
}
static bool AllChildGroups(const Group &group)
{
return std::find_if(std::begin(group.Children()), std::end(group.Children()), [](const Base* child) -> bool {
return dynamic_cast<const Group *>(child) && !child->Matched();
}) == std::end(group.Children());
}
static bool DontCare(const Group &)
{
return true;
}
static bool CareTooMuch(const Group &)
{
return false;
}
static bool None(const Group &group)
{
return group.MatchedChildren() == 0;
}
};
/// If help is empty, this group will not be printed in help output
Group(const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare) : Base(help_), validator(validator_) {}
/// If help is empty, this group will not be printed in help output
Group(Group &group_, const std::string &help_ = std::string(), const std::function<bool(const Group &)> &validator_ = Validators::DontCare) : Base(help_), validator(validator_)
{
group_.Add(*this);
}
virtual ~Group() {}
/** Return the first FlagBase that matches flag, or nullptr
*
* \param flag The flag with prefixes stripped
* \return the first matching FlagBase pointer, or nullptr if there is no match
*/
template <typename T>
FlagBase *Match(const T &flag)
{
for (Base *child: children)
{
if (FlagBase *flagBase = dynamic_cast<FlagBase *>(child))
{
if (FlagBase *match = flagBase->Match(flag))
{
return match;
}
} else if (Group *group = dynamic_cast<Group *>(child))
{
if (FlagBase *match = group->Match(flag))
{
return match;
}
}
}
return nullptr;
}
virtual void Validate(const std::string &shortPrefix, const std::string &longPrefix) override
{
for (Base *child: children)
{
child->Validate(shortPrefix, longPrefix);
}
}
/** Get the next ready positional, or nullptr if there is none
*
* \return the first ready PositionalBase pointer, or nullptr if there is no match
*/
PositionalBase *GetNextPositional()
{
for (Base *child: children)
{
auto next = dynamic_cast<PositionalBase *>(child);
auto group = dynamic_cast<Group *>(child);
if (group)
{
next = group->GetNextPositional();
}
if (next && next->Ready())
{
return next;
}
}
return nullptr;
}
/** Get whether this has any FlagBase children
*
* \return Whether or not there are any FlagBase children
*/
bool HasFlag() const
{
for (Base *child: children)
{
if (dynamic_cast<FlagBase *>(child))
{
return true;
}
if (auto group = dynamic_cast<Group *>(child))
{
if (group->HasFlag())
{
return true;
}
}
}
return false;
}
/** Append a child to this Group.
*/
void Add(Base &child)
{
children.emplace_back(&child);
}
/** Get all this group's children
*/
const std::vector<Base *> &Children() const
{
return children;
}
/** Count the number of matched children this group has
*/
std::vector<Base *>::size_type MatchedChildren() const
{
return std::count_if(std::begin(children), std::end(children), [](const Base *child){return child->Matched();});
}
/** Whether or not this group matches validation
*/
virtual bool Matched() const noexcept override
{
return validator(*this);
}
/** Get validation
*/
bool Get() const
{
return Matched();
}
/** Get all the child descriptions for help generation
*/
std::vector<std::tuple<std::string, std::string, unsigned int>> GetChildDescriptions(const std::string &shortPrefix, const std::string &longPrefix, const std::string &shortSeparator, const std::string &longSeparator, const unsigned int indent = 0) const
{
std::vector<std::tuple<std::string, std::string, unsigned int>> descriptions;
for (const auto &child: children)
{
if ((child->GetOptions() & Options::Hidden) != Options::None)
{
continue;
}
if (const auto group = dynamic_cast<Group *>(child))
{
// Push that group description on the back if not empty
unsigned char addindent = 0;
if (!group->help.empty())
{
descriptions.emplace_back(group->help, "", indent);
addindent = 1;
}
auto groupDescriptions = group->GetChildDescriptions(shortPrefix, longPrefix, shortSeparator, longSeparator, indent + addindent);
descriptions.insert(
std::end(descriptions),
std::make_move_iterator(std::begin(groupDescriptions)),
std::make_move_iterator(std::end(groupDescriptions)));
} else if (const auto named = dynamic_cast<NamedBase *>(child))
{
const auto description = named->GetDescription(shortPrefix, longPrefix, shortSeparator, longSeparator);
descriptions.emplace_back(std::get<0>(description), std::get<1>(description), indent);
}
}
return descriptions;
}
/** Get the names of positional parameters
*/
std::vector<std::string> GetPosNames() const
{
std::vector <std::string> names;
for (const auto &child: children)
{
if (const Group *group = dynamic_cast<Group *>(child))
{
auto groupNames = group->GetPosNames();
names.insert(
std::end(names),
std::make_move_iterator(std::begin(groupNames)),
std::make_move_iterator(std::end(groupNames)));
} else if (const PositionalBase *pos = dynamic_cast<PositionalBase *>(child))
{
names.emplace_back(pos->Name());
}
}
return names;
}
virtual void Reset() noexcept override
{
for (auto &child: children)
{
child->Reset();
}
#ifdef ARGS_NOEXCEPT
error = Error::None;
#endif
}
#ifdef ARGS_NOEXCEPT
/// Only for ARGS_NOEXCEPT
virtual Error GetError() const override
{
if (error != Error::None)
{
return error;
}
auto it = std::find_if(std::begin(children), std::end(children), [](const Base *child){return child->GetError() != Error::None;});
if (it == std::end(children))
{
return Error::None;
} else
{
return (*it)->GetError();
}
}
#endif
};
/** The main user facing command line argument parser class
*/
class ArgumentParser : public Group
{
private:
std::string prog;
std::string proglinePostfix;
std::string description;
std::string epilog;
std::string longprefix;
std::string shortprefix;
std::string longseparator;
std::string terminator;
bool allowJoinedShortValue;
bool allowJoinedLongValue;
bool allowSeparateShortValue;
bool allowSeparateLongValue;
protected:
bool RaiseParseError(const std::string &message)
{
#ifdef ARGS_NOEXCEPT
(void)message;
error = Error::Parse;
return false;
#else
throw ParseError(message);
#endif
}
enum class OptionType
{
LongFlag,
ShortFlag,
Positional
};
OptionType ParseOption(const std::string &s)
{
if (s.find(longprefix) == 0 && s.length() > longprefix.length())
{
return OptionType::LongFlag;
}
if (s.find(shortprefix) == 0 && s.length() > shortprefix.length())
{
return OptionType::ShortFlag;
}
return OptionType::Positional;
}
/** (INTERNAL) Parse flag's values
*
* \param arg The string to display in error message as a flag name
* \param[in, out] it The iterator to first value. It will point to the last value
* \param end The end iterator
* \param joinedArg Joined value (e.g. bar in --foo=bar)
* \param canDiscardJoined If true joined value can be parsed as flag not as a value (as in -abcd)
* \param[out] values The vector to store parsed arg's values
*/
template <typename It>
bool ParseArgsValues(FlagBase &flag, const std::string &arg, It &it, It end,
const bool allowSeparate, const bool allowJoined,
const bool hasJoined, const std::string &joinedArg,
const bool canDiscardJoined, std::vector<std::string> &values)
{
values.clear();
Nargs nargs = flag.NumberOfArguments();
if (hasJoined && !allowJoined && nargs.min != 0)
{
return RaiseParseError("Flag '" + arg + "' was passed a joined argument, but these are disallowed");
}
if (hasJoined)
{
if (!canDiscardJoined || nargs.max != 0)
{
values.push_back(joinedArg);
}
} else if (!allowSeparate)
{
if (nargs.min != 0)
{
return RaiseParseError("Flag '" + arg + "' was passed a separate argument, but these are disallowed");
}
} else
{
auto valueIt = it;
++valueIt;
while (valueIt != end &&
values.size() < nargs.max &&
(nargs.min == nargs.max || ParseOption(*valueIt) == OptionType::Positional))
{
values.push_back(*valueIt);
++it;
++valueIt;
}
}
if (values.size() > nargs.max)
{
return RaiseParseError("Passed an argument into a non-argument flag: " + arg);
} else if (values.size() < nargs.min)
{
if (nargs.min == 1 && nargs.max == 1)
{
return RaiseParseError("Flag '" + arg + "' requires an argument but received none");
} else if (nargs.min == 1)
{
return RaiseParseError("Flag '" + arg + "' requires at least one argument but received none");
} else if (nargs.min != nargs.max)
{
return RaiseParseError("Flag '" + arg + "' requires at least " + std::to_string(nargs.min) +
" arguments but received " + std::to_string(values.size()));
} else
{
return RaiseParseError("Flag '" + arg + "' requires " + std::to_string(nargs.min) +
" arguments but received " + std::to_string(values.size()));
}
}
return true;
}
template <typename It>
bool ParseLong(It &it, It end)
{
const auto &chunk = *it;
const auto argchunk = chunk.substr(longprefix.size());
// Try to separate it, in case of a separator:
const auto separator = longseparator.empty() ? argchunk.npos : argchunk.find(longseparator);
// If the separator is in the argument, separate it.
const auto arg = (separator != argchunk.npos ?
std::string(argchunk, 0, separator)
: argchunk);
const auto joined = (separator != argchunk.npos ?
argchunk.substr(separator + longseparator.size())
: std::string());
if (auto flag = Match(arg))
{
std::vector<std::string> values;
if (!ParseArgsValues(*flag, arg, it, end, allowSeparateLongValue, allowJoinedLongValue,
separator != argchunk.npos, joined, false, values))
{
return false;
}
flag->ParseValue(values);
if (flag->KickOut())
{
++it;
return false;
}
} else
{
return RaiseParseError("Flag could not be matched: " + arg);
}
return true;
}
template <typename It>
bool ParseShort(It &it, It end)
{
const auto &chunk = *it;
const auto argchunk = chunk.substr(shortprefix.size());
for (auto argit = std::begin(argchunk); argit != std::end(argchunk); ++argit)
{
const auto arg = *argit;
if (auto flag = Match(arg))
{
const std::string value(argit + 1, std::end(argchunk));
std::vector<std::string> values;
if (!ParseArgsValues(*flag, std::string(1, arg), it, end,
allowSeparateShortValue, allowJoinedShortValue,
!value.empty(), value, !value.empty(), values))
{
return false;
}
flag->ParseValue(values);
if (flag->KickOut())
{
++it;
return false;
}
if (!values.empty())
{
break;
}
} else
{
return RaiseParseError("Flag could not be matched: '" + std::string(1, arg) + "'");
}
}
return true;
}
public:
/** A simple structure of parameters for easy user-modifyable help menus
*/
struct HelpParams
{
/** The width of the help menu
*/
unsigned int width = 80;
/** The indent of the program line
*/
unsigned int progindent = 2;
/** The indent of the program trailing lines for long parameters
*/
unsigned int progtailindent = 4;
/** The indent of the description and epilogs
*/
unsigned int descriptionindent = 4;
/** The indent of the flags
*/
unsigned int flagindent = 6;
/** The indent of the flag descriptions
*/
unsigned int helpindent = 40;
/** The additional indent each group adds
*/
unsigned int eachgroupindent = 2;
/** The minimum gutter between each flag and its help
*/
unsigned int gutter = 1;
/** Show the terminator when both options and positional parameters are present
*/
bool showTerminator = true;
/** Show the {OPTIONS} on the prog line when this is true
*/
bool showProglineOptions = true;
/** Show the positionals on the prog line when this is true
*/
bool showProglinePositionals = true;
} helpParams;
ArgumentParser(const std::string &description_, const std::string &epilog_ = std::string()) :
Group("", Group::Validators::AllChildGroups),
description(description_),
epilog(epilog_),
longprefix("--"),
shortprefix("-"),
longseparator("="),
terminator("--"),
allowJoinedShortValue(true),
allowJoinedLongValue(true),
allowSeparateShortValue(true),
allowSeparateLongValue(true) {}
/** The program name for help generation
*/
const std::string &Prog() const
{ return prog; }
/** The program name for help generation
*/
void Prog(const std::string &prog_)
{ this->prog = prog_; }
/** The description that appears on the prog line after options
*/
const std::string &ProglinePostfix() const
{ return proglinePostfix; }
/** The description that appears on the prog line after options
*/
void ProglinePostfix(const std::string &proglinePostfix_)
{ this->proglinePostfix = proglinePostfix_; }
/** The description that appears above options
*/
const std::string &Description() const
{ return description; }
/** The description that appears above options
*/
void Description(const std::string &description_)
{ this->description = description_; }
/** The description that appears below options
*/
const std::string &Epilog() const
{ return epilog; }
/** The description that appears below options
*/
void Epilog(const std::string &epilog_)
{ this->epilog = epilog_; }
/** The prefix for long flags
*/
const std::string &LongPrefix() const
{ return longprefix; }
/** The prefix for long flags
*/
void LongPrefix(const std::string &longprefix_)
{ this->longprefix = longprefix_; }
/** The prefix for short flags
*/
const std::string &ShortPrefix() const
{ return shortprefix; }
/** The prefix for short flags
*/
void ShortPrefix(const std::string &shortprefix_)
{ this->shortprefix = shortprefix_; }
/** The separator for long flags
*/
const std::string &LongSeparator() const
{ return longseparator; }
/** The separator for long flags
*/
void LongSeparator(const std::string &longseparator_)
{
if (longseparator_.empty())
{
#ifdef ARGS_NOEXCEPT
error = Error::Usage;
#else
throw UsageError("longseparator can not be set to empty");
#endif
} else
{
this->longseparator = longseparator_;
}
}
/** The terminator that forcibly separates flags from positionals
*/
const std::string &Terminator() const
{ return terminator; }
/** The terminator that forcibly separates flags from positionals
*/
void Terminator(const std::string &terminator_)
{ this->terminator = terminator_; }
/** Get the current argument separation parameters.
*
* See SetArgumentSeparations for details on what each one means.
*/
void GetArgumentSeparations(
bool &allowJoinedShortValue_,
bool &allowJoinedLongValue_,
bool &allowSeparateShortValue_,
bool &allowSeparateLongValue_) const
{
allowJoinedShortValue_ = this->allowJoinedShortValue;
allowJoinedLongValue_ = this->allowJoinedLongValue;
allowSeparateShortValue_ = this->allowSeparateShortValue;
allowSeparateLongValue_ = this->allowSeparateLongValue;
}
/** Change allowed option separation.
*
* \param allowJoinedShortValue Allow a short flag that accepts an argument to be passed its argument immediately next to it (ie. in the same argv field)
* \param allowJoinedLongValue Allow a long flag that accepts an argument to be passed its argument separated by the longseparator (ie. in the same argv field)
* \param allowSeparateShortValue Allow a short flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)
* \param allowSeparateLongValue Allow a long flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field)
*/
void SetArgumentSeparations(
const bool allowJoinedShortValue_,
const bool allowJoinedLongValue_,
const bool allowSeparateShortValue_,
const bool allowSeparateLongValue_)
{
this->allowJoinedShortValue = allowJoinedShortValue_;
this->allowJoinedLongValue = allowJoinedLongValue_;
this->allowSeparateShortValue = allowSeparateShortValue_;
this->allowSeparateLongValue = allowSeparateLongValue_;
}
/** Pass the help menu into an ostream
*/
void Help(std::ostream &help_) const
{
bool hasoptions = false;
bool hasarguments = false;
const auto description_text = Wrap(this->description, helpParams.width - helpParams.descriptionindent);
const auto epilog_text = Wrap(this->epilog, helpParams.width - helpParams.descriptionindent);
std::ostringstream prognameline;
prognameline << prog;
if (HasFlag())
{
hasoptions = true;
if (helpParams.showProglineOptions)
{
prognameline << " {OPTIONS}";
}
}
for (const std::string &posname: GetPosNames())
{
hasarguments = true;
if (helpParams.showProglinePositionals)
{
prognameline << " [" << posname << ']';
}
}
if (!proglinePostfix.empty())
{
prognameline << ' ' << proglinePostfix;
}
const auto proglines = Wrap(prognameline.str(), helpParams.width - (helpParams.progindent + 4), helpParams.width - helpParams.progindent);
auto progit = std::begin(proglines);
if (progit != std::end(proglines))
{
help_ << std::string(helpParams.progindent, ' ') << *progit << '\n';
++progit;
}
for (; progit != std::end(proglines); ++progit)
{
help_ << std::string(helpParams.progtailindent, ' ') << *progit << '\n';
}
help_ << '\n';
for (const auto &line: description_text)
{
help_ << std::string(helpParams.descriptionindent, ' ') << line << "\n";
}
help_ << "\n";
help_ << std::string(helpParams.progindent, ' ') << "OPTIONS:\n\n";
for (const auto &desc: GetChildDescriptions(shortprefix, longprefix, allowJoinedShortValue ? "" : " ", allowJoinedLongValue ? longseparator : " "))
{
const auto groupindent = std::get<2>(desc) * helpParams.eachgroupindent;
const auto flags = Wrap(std::get<0>(desc), helpParams.width - (helpParams.flagindent + helpParams.helpindent + helpParams.gutter));
const auto info = Wrap(std::get<1>(desc), helpParams.width - (helpParams.helpindent + groupindent));
std::string::size_type flagssize = 0;
for (auto flagsit = std::begin(flags); flagsit != std::end(flags); ++flagsit)
{
if (flagsit != std::begin(flags))
{
help_ << '\n';
}
help_ << std::string(groupindent + helpParams.flagindent, ' ') << *flagsit;
flagssize = Glyphs(*flagsit);
}
auto infoit = std::begin(info);
// groupindent is on both sides of this inequality, and therefore can be removed
if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info))
{
help_ << '\n';
} else
{
// groupindent is on both sides of the minus sign, and therefore doesn't actually need to be in here
help_ << std::string(helpParams.helpindent - (helpParams.flagindent + flagssize), ' ') << *infoit << '\n';
++infoit;
}
for (; infoit != std::end(info); ++infoit)
{
help_ << std::string(groupindent + helpParams.helpindent, ' ') << *infoit << '\n';
}
}
if (hasoptions && hasarguments && helpParams.showTerminator)
{
for (const auto &item: Wrap(std::string("\"") + terminator + "\" can be used to terminate flag options and force all following arguments to be treated as positional options", helpParams.width - helpParams.flagindent))
{
help_ << std::string(helpParams.flagindent, ' ') << item << '\n';
}
}
help_ << "\n";
for (const auto &line: epilog_text)
{
help_ << std::string(helpParams.descriptionindent, ' ') << line << "\n";
}
}
/** Generate a help menu as a string.
*
* \return the help text as a single string
*/
std::string Help() const
{
std::ostringstream help_;
Help(help_);
return help_.str();
}
/** Parse all arguments.
*
* \param begin an iterator to the beginning of the argument list
* \param end an iterator to the past-the-end element of the argument list
* \return the iterator after the last parsed value. Only useful for kick-out
*/
template <typename It>
It ParseArgs(It begin, It end)
{
// Reset all Matched statuses and errors
Reset();
bool terminated = false;
// Check all arg chunks
for (auto it = begin; it != end; ++it)
{
const auto &chunk = *it;
if (!terminated && chunk == terminator)
{
terminated = true;
} else if (!terminated && ParseOption(chunk) == OptionType::LongFlag)
{
if (!ParseLong(it, end))
{
return it;
}
} else if (!terminated && ParseOption(chunk) == OptionType::ShortFlag)
{
if (!ParseShort(it, end))
{
return it;
}
} else
{
auto pos = GetNextPositional();
if (pos)
{
pos->ParseValue(chunk);
if (pos->KickOut())
{
return ++it;
}
} else
{
RaiseParseError("Passed in argument, but no positional arguments were ready to receive it: " + chunk);
return it;
}
}
}
for (Base *child: Children())
{
child->Validate(shortprefix, longprefix);
}
if (!Matched())
{
#ifdef ARGS_NOEXCEPT
error = Error::Validation;
#else
std::ostringstream problem;
problem << "Group validation failed somewhere!";
throw ValidationError(problem.str());
#endif
}
return end;
}
/** Parse all arguments.
*
* \param args an iterable of the arguments
* \return the iterator after the last parsed value. Only useful for kick-out
*/
template <typename T>
auto ParseArgs(const T &args) -> decltype(std::begin(args))
{
return ParseArgs(std::begin(args), std::end(args));
}
/** Convenience function to parse the CLI from argc and argv
*
* Just assigns the program name and vectorizes arguments for passing into ParseArgs()
*
* \return whether or not all arguments were parsed. This works for detecting kick-out, but is generally useless as it can't do anything with it.
*/
bool ParseCLI(const int argc, const char * const * argv)
{
if (prog.empty())
{
prog.assign(argv[0]);
}
const std::vector<std::string> args(argv + 1, argv + argc);
return ParseArgs(args) == std::end(args);
}
};
inline std::ostream &operator<<(std::ostream &os, const ArgumentParser &parser)
{
parser.Help(os);
return os;
}
/** Boolean argument matcher
*/
class Flag : public FlagBase
{
public:
Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): FlagBase(name_, help_, std::move(matcher_), options_)
{
group_.Add(*this);
}
Flag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const bool extraError_ = false): Flag(group_, name_, help_, std::move(matcher_), extraError_ ? Options::Single : Options::None)
{
}
virtual ~Flag() {}
/** Get whether this was matched
*/
bool Get() const
{
return Matched();
}
virtual Nargs NumberOfArguments() const noexcept override
{
return 0;
}
virtual void ParseValue(const std::vector<std::string>&) override
{
}
};
/** Help flag class
*
* Works like a regular flag, but throws an instance of Help when it is matched
*/
class HelpFlag : public Flag
{
public:
HelpFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_): Flag(group_, name_, help_, std::move(matcher_)) {}
virtual ~HelpFlag() {}
virtual FlagBase *Match(const std::string &arg) override
{
if (FlagBase::Match(arg))
{
#ifdef ARGS_NOEXCEPT
error = Error::Help;
return this;
#else
throw Help(arg);
#endif
}
return nullptr;
}
virtual FlagBase *Match(const char arg) override
{
if (FlagBase::Match(arg))
{
#ifdef ARGS_NOEXCEPT
error = Error::Help;
return this;
#else
throw Help(std::string(1, arg));
#endif
}
return nullptr;
}
/** Get whether this was matched
*/
bool Get() const noexcept
{
return Matched();
}
};
/** A flag class that simply counts the number of times it's matched
*/
class CounterFlag : public Flag
{
private:
const int startcount;
int count;
public:
CounterFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const int startcount_ = 0): Flag(group_, name_, help_, std::move(matcher_)), startcount(startcount_), count(startcount_) {}
virtual ~CounterFlag() {}
virtual FlagBase *Match(const std::string &arg) override
{
auto me = FlagBase::Match(arg);
if (me)
{
++count;
}
return me;
}
virtual FlagBase *Match(const char arg) override
{
auto me = FlagBase::Match(arg);
if (me)
{
++count;
}
return me;
}
/** Get the count
*/
int &Get() noexcept
{
return count;
}
virtual void Reset() noexcept override
{
FlagBase::Reset();
count = startcount;
}
};
/** A default Reader class for argument classes
*
* Simply uses a std::istringstream to read into the destination type, and
* raises a ParseError if there are any characters left.
*/
template <typename T>
struct ValueReader
{
bool operator ()(const std::string &name, const std::string &value, T &destination)
{
std::istringstream ss(value);
ss >> destination;
if (ss.rdbuf()->in_avail() > 0)
{
#ifdef ARGS_NOEXCEPT
return false;
#else
std::ostringstream problem;
problem << "Argument '" << name << "' received invalid value type '" << value << "'";
throw ParseError(problem.str());
#endif
}
return true;
}
};
/** std::string specialization for ValueReader
*
* By default, stream extraction into a string splits on white spaces, and
* it is more efficient to ust copy a string into the destination.
*/
template <>
struct ValueReader<std::string>
{
bool operator()(const std::string &, const std::string &value, std::string &destination)
{
destination.assign(value);
return true;
}
};
/** An argument-accepting flag class
*
* \tparam T the type to extract the argument as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
typename Reader = ValueReader<T>>
class ValueFlag : public ValueFlagBase
{
protected:
T value;
private:
Reader reader;
public:
ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), value(defaultValue_)
{
group_.Add(*this);
}
ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), const bool extraError_ = false): ValueFlag(group_, name_, help_, std::move(matcher_), defaultValue_, extraError_ ? Options::Single : Options::None)
{
}
ValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_): ValueFlag(group_, name_, help_, std::move(matcher_), T(), options_)
{
}
virtual ~ValueFlag() {}
virtual void ParseValue(const std::vector<std::string> &values_) override
{
const std::string &value_ = values_.at(0);
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, this->value))
{
error = Error::Parse;
}
#else
reader(name, value_, this->value);
#endif
}
/** Get the value
*/
T &Get() noexcept
{
return value;
}
};
/** An optional argument-accepting flag class
*
* \tparam T the type to extract the argument as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
typename Reader = ValueReader<T>>
class ImplicitValueFlag : public ValueFlag<T, Reader>
{
protected:
T implicitValue;
T defaultValue;
public:
ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &implicitValue_, const T &defaultValue_ = T(), Options options_ = {})
: ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(implicitValue_), defaultValue(defaultValue_)
{
}
ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const T &defaultValue_ = T(), Options options_ = {})
: ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(defaultValue_), defaultValue(defaultValue_)
{
}
ImplicitValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Options options_)
: ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), {}, options_), implicitValue(), defaultValue()
{
}
virtual ~ImplicitValueFlag() {}
virtual Nargs NumberOfArguments() const noexcept override
{
return {0, 1};
}
virtual void ParseValue(const std::vector<std::string> &value_) override
{
if (value_.empty())
{
this->value = implicitValue;
} else
{
ValueFlag<T, Reader>::ParseValue(value_);
}
}
virtual void Reset() noexcept override
{
this->value = defaultValue;
ValueFlag<T, Reader>::Reset();
}
};
/** A variadic arguments accepting flag class
*
* \tparam T the type to extract the argument as
* \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
template <typename...> class List = std::vector,
typename Reader = ValueReader<T>>
class NargsValueFlag : public FlagBase
{
protected:
List<T> values;
Nargs nargs;
Reader reader;
public:
typedef List<T> Container;
typedef T value_type;
typedef typename Container::allocator_type allocator_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
NargsValueFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, Nargs nargs_, const List<T> &defaultValues_ = {}, Options options_ = {})
: FlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), nargs(nargs_)
{
group_.Add(*this);
}
virtual ~NargsValueFlag() {}
virtual Nargs NumberOfArguments() const noexcept override
{
return nargs;
}
virtual void ParseValue(const std::vector<std::string> &values_) override
{
values.clear();
for (const std::string &value : values_)
{
T v;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value, v))
{
error = Error::Parse;
}
#else
reader(name, value, v);
#endif
values.insert(std::end(values), v);
}
}
List<T> &Get() noexcept
{
return values;
}
iterator begin() noexcept
{
return values.begin();
}
const_iterator begin() const noexcept
{
return values.begin();
}
const_iterator cbegin() const noexcept
{
return values.cbegin();
}
iterator end() noexcept
{
return values.end();
}
const_iterator end() const noexcept
{
return values.end();
}
const_iterator cend() const noexcept
{
return values.cend();
}
};
/** An argument-accepting flag class that pushes the found values into a list
*
* \tparam T the type to extract the argument as
* \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
template <typename...> class List = std::vector,
typename Reader = ValueReader<T>>
class ValueFlagList : public ValueFlagBase
{
private:
using Container = List<T>;
Container values;
Reader reader;
public:
typedef T value_type;
typedef typename Container::allocator_type allocator_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
ValueFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Container &defaultValues_ = Container()): ValueFlagBase(name_, help_, std::move(matcher_)), values(defaultValues_)
{
group_.Add(*this);
}
virtual ~ValueFlagList() {}
virtual void ParseValue(const std::vector<std::string> &values_) override
{
const std::string &value_ = values_.at(0);
T v;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, v))
{
error = Error::Parse;
}
#else
reader(name, value_, v);
#endif
values.insert(std::end(values), v);
}
/** Get the values
*/
Container &Get() noexcept
{
return values;
}
virtual std::string Name() const override
{
return name + std::string("...");
}
virtual void Reset() noexcept override
{
ValueFlagBase::Reset();
values.clear();
}
iterator begin() noexcept
{
return values.begin();
}
const_iterator begin() const noexcept
{
return values.begin();
}
const_iterator cbegin() const noexcept
{
return values.cbegin();
}
iterator end() noexcept
{
return values.end();
}
const_iterator end() const noexcept
{
return values.end();
}
const_iterator cend() const noexcept
{
return values.cend();
}
};
/** A mapping value flag class
*
* \tparam K the type to extract the argument as
* \tparam T the type to store the result as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
* \tparam Map The Map type. Should operate like std::map or std::unordered_map
*/
template <
typename K,
typename T,
typename Reader = ValueReader<K>,
template <typename...> class Map = std::unordered_map>
class MapFlag : public ValueFlagBase
{
private:
const Map<K, T> map;
T value;
Reader reader;
public:
MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_, Options options_): ValueFlagBase(name_, help_, std::move(matcher_), options_), map(map_), value(defaultValue_)
{
group_.Add(*this);
}
MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const T &defaultValue_ = T(), const bool extraError_ = false): MapFlag(group_, name_, help_, std::move(matcher_), map_, defaultValue_, extraError_ ? Options::Single : Options::None)
{
}
MapFlag(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, Options options_): MapFlag(group_, name_, help_, std::move(matcher_), map_, T(), options_)
{
}
virtual ~MapFlag() {}
virtual void ParseValue(const std::vector<std::string> &values_) override
{
const std::string &value_ = values_.at(0);
K key;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, key))
{
error = Error::Parse;
}
#else
reader(name, value_, key);
#endif
auto it = map.find(key);
if (it == std::end(map))
{
#ifdef ARGS_NOEXCEPT
error = Error::Map;
#else
std::ostringstream problem;
problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
throw MapError(problem.str());
#endif
} else
{
this->value = it->second;
}
}
/** Get the value
*/
T &Get() noexcept
{
return value;
}
};
/** A mapping value flag list class
*
* \tparam K the type to extract the argument as
* \tparam T the type to store the result as
* \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
* \tparam Map The Map type. Should operate like std::map or std::unordered_map
*/
template <
typename K,
typename T,
template <typename...> class List = std::vector,
typename Reader = ValueReader<K>,
template <typename...> class Map = std::unordered_map>
class MapFlagList : public ValueFlagBase
{
private:
using Container = List<T>;
const Map<K, T> map;
Container values;
Reader reader;
public:
typedef T value_type;
typedef typename Container::allocator_type allocator_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
MapFlagList(Group &group_, const std::string &name_, const std::string &help_, Matcher &&matcher_, const Map<K, T> &map_, const Container &defaultValues_ = Container()): ValueFlagBase(name_, help_, std::move(matcher_)), map(map_), values(defaultValues_)
{
group_.Add(*this);
}
virtual ~MapFlagList() {}
virtual void ParseValue(const std::vector<std::string> &values_) override
{
const std::string &value = values_.at(0);
K key;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value, key))
{
error = Error::Parse;
}
#else
reader(name, value, key);
#endif
auto it = map.find(key);
if (it == std::end(map))
{
#ifdef ARGS_NOEXCEPT
error = Error::Map;
#else
std::ostringstream problem;
problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
throw MapError(problem.str());
#endif
} else
{
this->values.emplace_back(it->second);
}
}
/** Get the value
*/
Container &Get() noexcept
{
return values;
}
virtual std::string Name() const override
{
return name + std::string("...");
}
virtual void Reset() noexcept override
{
ValueFlagBase::Reset();
values.clear();
}
iterator begin() noexcept
{
return values.begin();
}
const_iterator begin() const noexcept
{
return values.begin();
}
const_iterator cbegin() const noexcept
{
return values.cbegin();
}
iterator end() noexcept
{
return values.end();
}
const_iterator end() const noexcept
{
return values.end();
}
const_iterator cend() const noexcept
{
return values.cend();
}
};
/** A positional argument class
*
* \tparam T the type to extract the argument as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
typename Reader = ValueReader<T>>
class Positional : public PositionalBase
{
private:
T value;
Reader reader;
public:
Positional(Group &group_, const std::string &name_, const std::string &help_, const T &defaultValue_ = T(), Options options_ = Options::None): PositionalBase(name_, help_, options_), value(defaultValue_)
{
group_.Add(*this);
}
Positional(Group &group_, const std::string &name_, const std::string &help_, Options options_): Positional(group_, name_, help_, T(), options_)
{
}
virtual ~Positional() {}
virtual void ParseValue(const std::string &value_) override
{
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, this->value))
{
error = Error::Parse;
}
#else
reader(name, value_, this->value);
#endif
ready = false;
matched = true;
}
/** Get the value
*/
T &Get() noexcept
{
return value;
}
};
/** A positional argument class that pushes the found values into a list
*
* \tparam T the type to extract the argument as
* \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
*/
template <
typename T,
template <typename...> class List = std::vector,
typename Reader = ValueReader<T>>
class PositionalList : public PositionalBase
{
private:
using Container = List<T>;
Container values;
Reader reader;
public:
typedef T value_type;
typedef typename Container::allocator_type allocator_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
PositionalList(Group &group_, const std::string &name_, const std::string &help_, const Container &defaultValues_ = Container()): PositionalBase(name_, help_), values(defaultValues_)
{
group_.Add(*this);
}
virtual ~PositionalList() {}
virtual void ParseValue(const std::string &value_) override
{
T v;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, v))
{
error = Error::Parse;
}
#else
reader(name, value_, v);
#endif
values.insert(std::end(values), v);
matched = true;
}
virtual std::string Name() const override
{
return name + std::string("...");
}
/** Get the values
*/
Container &Get() noexcept
{
return values;
}
virtual void Reset() noexcept override
{
PositionalBase::Reset();
values.clear();
}
iterator begin() noexcept
{
return values.begin();
}
const_iterator begin() const noexcept
{
return values.begin();
}
const_iterator cbegin() const noexcept
{
return values.cbegin();
}
iterator end() noexcept
{
return values.end();
}
const_iterator end() const noexcept
{
return values.end();
}
const_iterator cend() const noexcept
{
return values.cend();
}
};
/** A positional argument mapping class
*
* \tparam K the type to extract the argument as
* \tparam T the type to store the result as
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
* \tparam Map The Map type. Should operate like std::map or std::unordered_map
*/
template <
typename K,
typename T,
typename Reader = ValueReader<K>,
template <typename...> class Map = std::unordered_map>
class MapPositional : public PositionalBase
{
private:
const Map<K, T> map;
T value;
Reader reader;
public:
MapPositional(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const T &defaultValue_ = T()): PositionalBase(name_, help_), map(map_), value(defaultValue_)
{
group_.Add(*this);
}
virtual ~MapPositional() {}
virtual void ParseValue(const std::string &value_) override
{
K key;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, key))
{
error = Error::Parse;
}
#else
reader(name, value_, key);
#endif
auto it = map.find(key);
if (it == std::end(map))
{
#ifdef ARGS_NOEXCEPT
error = Error::Map;
#else
std::ostringstream problem;
problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
throw MapError(problem.str());
#endif
} else
{
this->value = it->second;
ready = false;
matched = true;
}
}
/** Get the value
*/
T &Get() noexcept
{
return value;
}
};
/** A positional argument mapping list class
*
* \tparam K the type to extract the argument as
* \tparam T the type to store the result as
* \tparam List the list type that houses the values
* \tparam Reader The functor type used to read the argument, taking the name, value, and destination reference with operator(), and returning a bool (if ARGS_NOEXCEPT is defined)
* \tparam Map The Map type. Should operate like std::map or std::unordered_map
*/
template <
typename K,
typename T,
template <typename...> class List = std::vector,
typename Reader = ValueReader<K>,
template <typename...> class Map = std::unordered_map>
class MapPositionalList : public PositionalBase
{
private:
using Container = List<T>;
const Map<K, T> map;
Container values;
Reader reader;
public:
typedef T value_type;
typedef typename Container::allocator_type allocator_type;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef typename Container::size_type size_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
MapPositionalList(Group &group_, const std::string &name_, const std::string &help_, const Map<K, T> &map_, const Container &defaultValues_ = Container()): PositionalBase(name_, help_), map(map_), values(defaultValues_)
{
group_.Add(*this);
}
virtual ~MapPositionalList() {}
virtual void ParseValue(const std::string &value_) override
{
K key;
#ifdef ARGS_NOEXCEPT
if (!reader(name, value_, key))
{
error = Error::Parse;
}
#else
reader(name, value_, key);
#endif
auto it = map.find(key);
if (it == std::end(map))
{
#ifdef ARGS_NOEXCEPT
error = Error::Map;
#else
std::ostringstream problem;
problem << "Could not find key '" << key << "' in map for arg '" << name << "'";
throw MapError(problem.str());
#endif
} else
{
this->values.emplace_back(it->second);
matched = true;
}
}
/** Get the value
*/
Container &Get() noexcept
{
return values;
}
virtual std::string Name() const override
{
return name + std::string("...");
}
virtual void Reset() noexcept override
{
PositionalBase::Reset();
values.clear();
}
iterator begin() noexcept
{
return values.begin();
}
const_iterator begin() const noexcept
{
return values.begin();
}
const_iterator cbegin() const noexcept
{
return values.cbegin();
}
iterator end() noexcept
{
return values.end();
}
const_iterator end() const noexcept
{
return values.end();
}
const_iterator cend() const noexcept
{
return values.cend();
}
};
}
#endif
================================================
FILE: asm-methods.asm
================================================
BITS 64
default rel
%if (__NASM_MAJOR__ < 2) || (__NASM_MINOR__ < 11)
%deftok ver __NASM_VER__
%error Your nasm version (ver) is too old, you need at least 2.11 to compile this
%endif
%include "nasm-utils-inc.asm"
nasm_util_assert_boilerplate
thunk_boilerplate
; aligns and declares the global label for the bench with the given name
; also potentally checks the ABI compliance (if enabled)
%macro define_func 1
abi_checked_function %1
%endmacro
; define a test func that unrolls the loop by 100
; with the given body instruction
; %1 - function name
; %2 - init instruction (e.g., xor out the variable you'll add to)
; %3 - loop body instruction
; %4 - repeat count, defaults to 100 - values other than 100 mean the Mops value will be wrong
%macro test_func 3-4 100
define_func %1
%2
.top:
times %4 %3
sub rdi, 100
jnz .top
ret
%endmacro
; pause
test_func pause_only, {}, {pause}, 1
; vpermw latency
test_func avx512_vpermw, {vpcmpeqd ymm0, ymm0, ymm0}, {vpermw zmm0, zmm0, zmm0}
; vpermb latency
test_func avx512_vpermd, {vpcmpeqd ymm0, ymm0, ymm0}, {vpermd zmm0, zmm0, zmm0}
; imul latency
test_func avx128_imul, {vpcmpeqd xmm0, xmm0, xmm0}, {vpmuldq xmm0, xmm0, xmm0}
test_func avx256_imul, {vpcmpeqd ymm0, ymm0, ymm0}, {vpmuldq ymm0, ymm0, ymm0}
test_func avx512_imul, {vpcmpeqd ymm0, ymm0, ymm0}, {vpmuldq zmm0, zmm0, zmm0}
; imul throughput
test_func avx128_imul_t, {vpcmpeqd xmm0, xmm0, xmm0}, {vpmuldq xmm0, xmm1, xmm1}
test_func avx256_imul_t, {vpcmpeqd ymm0, ymm0, ymm0}, {vpmuldq ymm0, ymm1, ymm1}
test_func avx512_imul_t, {vpcmpeqd ymm0, ymm0, ymm0}, {vpmuldq zmm0, zmm1, zmm1}
; iadd latency
test_func scalar_iadd, {xor eax, eax}, {add rax, rax}
test_func avx128_iadd, {vpcmpeqd xmm0, xmm0, xmm0}, {vpaddq xmm0, xmm0, xmm0}
test_func avx256_iadd, {vpcmpeqd ymm0, ymm0, ymm0}, {vpaddq ymm0, ymm0, ymm0}
test_func avx512_iadd, {vpcmpeqd ymm0, ymm0, ymm0}, {vpaddq zmm0, zmm0, zmm0}
; iadd latency with zmm16
test_func avx128_iadd16, {vpternlogd xmm16, xmm16, xmm16, 0xff}, {vpaddq xmm16, xmm16, xmm16}
test_func avx256_iadd16, {vpternlogd ymm16, ymm16, ymm16, 0xff}, {vpaddq ymm16, ymm16, ymm16}
test_func avx512_iadd16, {vpternlogd zmm16, zmm16, zmm16, 0xff}, {vpaddq zmm16, zmm16, zmm16}
; iadd throughput
test_func avx128_iadd_t, {vpcmpeqd xmm1, xmm0, xmm0}, {vpaddq xmm0, xmm1, xmm1}
test_func avx256_iadd_t, {vpcmpeqd ymm1, ymm0, ymm0}, {vpaddq ymm0, ymm1, ymm1}
; zeroing xor
test_func avx128_xor_zero, {}, {vpxor xmm0, xmm0, xmm0}
test_func avx256_xor_zero, {}, {vpxor ymm0, ymm0, ymm0}
test_func avx512_xor_zero, {}, {vpxord zmm0, zmm0, zmm0}
; vpsrlvd latency
test_func avx128_vshift, {vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd xmm0, xmm0, xmm0}
test_func avx256_vshift, {vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd ymm0, ymm0, ymm0}
test_func avx512_vshift, {vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd zmm0, zmm0, zmm0}
; vpsrlvd throughput
test_func avx128_vshift_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd xmm0, xmm1, xmm1}
test_func avx256_vshift_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd ymm0, ymm1, ymm1}
test_func avx512_vshift_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vpsrlvd zmm0, zmm1, zmm1}
; vplzcntd latency
test_func avx128_vlzcnt, {vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd xmm0, xmm0}
test_func avx256_vlzcnt, {vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd ymm0, ymm0}
test_func avx512_vlzcnt, {vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd zmm0, zmm0}
; vplzcntd throughput
test_func avx128_vlzcnt_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd xmm0, xmm1}
test_func avx256_vlzcnt_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd ymm0, ymm1}
test_func avx512_vlzcnt_t,{vpcmpeqd xmm1, xmm0, xmm0}, {vplzcntd zmm0, zmm1}
; FMA
test_func avx128_fma , {vpxor xmm0, xmm0, xmm0}, {vfmadd132pd xmm0, xmm0, xmm0}
test_func avx256_fma , {vpxor xmm0, xmm0, xmm0}, {vfmadd132pd ymm0, ymm0, ymm0}
test_func avx512_fma , {vpxor xmm0, xmm0, xmm0}, {vfmadd132pd zmm0, zmm0, zmm0}
; this is like test_func, but it uses 10 parallel chains of instructions,
; unrolled 10 times, so (probably) max throughput at least if latency * throughput
; product for the instruction <= 10
; %1 - function name
; %2 - init instruction (e.g., xor out the variable you'll add to)
; %3 - register base like xmm, ymm, zmm
; %4 - loop body instruction only (no operands)
; %5 - init value for xmm0-9, used as first (dest) arg as in vfmadd132pd xmm0..9, xmm10, xmm11
; %6 - init value for xmm10, used as second arg as in vfmadd132pd reg, xmm10, xmm11
; %7 - init value for xmm11, used as third arg as in vfmadd132pd reg, xmm10, xmm11
%macro test_func_tput 7
define_func %1
; init reg 0-9
%assign r 0
%rep 10
%2 %3 %+ r, %5
%assign r (r+1)
%endrep
; init reg10, reg11
%2 %3 %+ 10, %6
%2 %3 %+ 11, %7
.top:
%rep 10
%assign r 0
%rep 10
%4 %3 %+ r, %3 %+ 10, %3 %+ 11
%assign r (r+1)
%endrep
%endrep
sub rdi, 100
jnz .top
ret
%endmacro
test_func_tput avx128_fma_t , vmovddup, xmm, vfmadd132pd, [zero_dp], [one_dp], [half_dp]
test_func_tput avx256_fma_t , vbroadcastsd, ymm, vfmadd132pd, [zero_dp], [one_dp], [half_dp]
test_func_tput avx512_fma_t , vbroadcastsd, zmm, vfmadd132pd, [zero_dp], [one_dp], [half_dp]
test_func_tput avx512_vpermw_t ,vbroadcastsd, zmm, vpermw, [zero_dp], [one_dp], [half_dp]
test_func_tput avx512_vpermd_t ,vbroadcastsd, zmm, vpermd, [zero_dp], [one_dp], [half_dp]
; this is like test_func except that the 100x unrolled loop instruction is
; always a serial scalar add, while the passed instruction to test is only
; executed once per loop (so at a ratio of 1:100 for the scalar adds). This
; test the effect of an "occasional" AVX instruction.
; %1 - function name
; %2 - init instruction (e.g., xor out the variable you'll add to)
; %3 - loop body instruction
%macro test_func_sparse 4
define_func %1
%2
%4
xor eax, eax
.top:
%3
times 100 add eax, eax
sub rdi, 100
jnz .top
ret
%endmacro
test_func_sparse avx128_mov_sparse, {vbroadcastsd ymm0, [one_dp]}, {vmovdqa xmm0, xmm0}, {}
test_func_sparse avx256_mov_sparse, {vbroadcastsd ymm0, [one_dp]}, {vmovdqa ymm0, ymm0}, {}
test_func_sparse avx512_mov_sparse, {vbroadcastsd zmm0, [one_dp]}, {vmovdqa32 zmm0, zmm0}, {}
test_func_sparse avx128_merge_sparse, {vbroadcastsd ymm0, [one_dp]}, {vmovdqa32 xmm0{k1}, xmm0}, {kmovw k1, [kmask]}
test_func_sparse avx256_merge_sparse, {vbroadcastsd ymm0, [one_dp]}, {vmovdqa32 ymm0{k1}, ymm0}, {kmovw k1, [kmask]}
test_func_sparse avx512_merge_sparse, {vbroadcastsd zmm0, [one_dp]}, {vmovdqa32 zmm0{k1}, zmm0}, {kmovw k1, [kmask]}
test_func_sparse avx128_fma_sparse, {vbroadcastsd ymm0, [zero_dp]}, {vfmadd132pd xmm0, xmm0, xmm0 }, {}
test_func_sparse avx256_fma_sparse, {vbroadcastsd ymm0, [zero_dp]}, {vfmadd132pd ymm0, ymm0, ymm0 }, {}
test_func_sparse avx512_fma_sparse, {vbroadcastsd zmm0, [zero_dp]}, {vfmadd132pd zmm0, zmm0, zmm0 }, {}
; %1 function name suffix
; %2 dirty instruction
%macro define_ucomis 2
define_func ucomis_%1
;vpxor xmm15, xmm15, xmm15
;vzeroupper
%2
movdqu xmm0, [one_dp]
movdqu xmm2, [one_dp]
movdqu xmm1, [zero_dp]
align 64
.top:
%rep 100
addsd xmm0, xmm2
ucomisd xmm1, xmm0
ja .never
%endrep
sub rdi, 100
jnz .top
ret
.never:
ud2
%endmacro
define_ucomis clean, {vzeroupper}
define_ucomis dirty, {}
define_func dirty_it
vzeroupper
vpxord zmm15, zmm14, zmm15
ret
define_func dirty_it16
vzeroupper
vpxord zmm16, zmm14, zmm15
ret
GLOBAL zeroupper_asm:function
zeroupper_asm:
vzeroupper
ret
zero_dp: dq 0.0
half_dp: dq 0.5
one_dp: dq 1.0
kmask: dq 0x5555555555555555
================================================
FILE: atomic.h
================================================
/* Atomic operations (v1)
* Portable Snippets - https://gitub.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*
* This is a small abstraction layer for some common atomic operations
* (load, store, add, subtract, and compare & swap) implemented using
* various compiler-specific builtins.
*
* There are four types, 32-bit and 64-bit integers which are both
* atomic and non-atomic. The atomic versions should be used for the
* atomic variable, the non-atomic variables should be used to store
* values read from or written to an atomic variable. For example, a
* basic CAS loop:
*
* void square_dest(psnip_atomic_int64* value) {
* psnip_int64_t expected;
* do {
* expected = psnip_atomic_int64_load(&value);
* } while (!psnip_atomic_int64_compare_exchange(&value, &expected, expected * expected));
* }
*
* Most things are implemented with the preprocessor, but if they were
* functions the prototypes (the 64-bit versions, just s/64/32/ for
* the 32-bit versions) would loo like:
*
* psnip_int64_t psnip_atomic_int64_load(
* psnip_atomic_int64* object);
* void psnip_atomic_int64_store(
* psnip_atomic_int64* object,
* psnip_int64_t desired);
* _Bool psnip_atomic_int64_compare_exchange(
* psnip_atomic_int64* object,
* psnip_int64_t* expected,
* psnip_int64_t desired);
* psnip_int64_t psnip_atomic_int64_add(
* psnip_atomic_int64* object,
* psnip_int64_t operand);
* psnip_int64_t psnip_atomic_int64_sub(
* psnip_atomic_int64* object,
* psnip_int64_t operand);
*/
#if !defined(PSNIP_ATOMIC_H)
#define PSNIP_ATOMIC_H
#if !defined(psnip_int64_t) || !defined(psnip_int32_t)
# include "exact-int.h"
#endif
#if !defined(PSNIP_ATOMIC_STATIC_INLINE)
# if defined(__GNUC__)
# define PSNIP_ATOMIC__COMPILER_ATTRIBUTES __attribute__((__unused__))
# else
# define PSNIP_ATOMIC__COMPILER_ATTRIBUTES
# endif
# if defined(HEDLEY_INLINE)
# define PSNIP_ATOMIC__INLINE HEDLEY_INLINE
# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define PSNIP_ATOMIC__INLINE inline
# elif defined(__GNUC_STDC_INLINE__)
# define PSNIP_ATOMIC__INLINE __inline__
# elif defined(_MSC_VER) && _MSC_VER >= 1200
# define PSNIP_ATOMIC__INLINE __inline
# else
# define PSNIP_ATOMIC__INLINE
# endif
# define PSNIP_ATOMIC__FUNCTION PSNIP_ATOMIC__COMPILER_ATTRIBUTES static PSNIP_ATOMIC__INLINE
#endif
#if defined(__has_feature)
# define PSNIP_ATOMIC_HAS_FEATURE(feature) __has_feature(feature)
#else
# define PSNIP_ATOMIC_HAS_FEATURE(feature) 0
#endif
#define PSNIP_ATOMIC_IMPL_NONE 0
#define PSNIP_ATOMIC_IMPL_GCC 1
#define PSNIP_ATOMIC_IMPL_GCC_SYNC 2
#define PSNIP_ATOMIC_IMPL_CLANG 3
#define PSNIP_ATOMIC_IMPL_MS 4
#define PSNIP_ATOMIC_IMPL_OPENMP 5
#define PSNIP_ATOMIC_IMPL_C11 11
#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_GCC
#elif !defined(__INTEL_COMPILER) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
/* GCC 4.7 and 4.8 sets __STDC_VERSION__ to C11 (if compiling in C11
* mode) and didn't have stdatomic.h, but failed to set
* __STDC_NO_ATOMICS__. Verions prior to 4.7 didn't set
* __STDC_VERSION__ to C11. */
# if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 9)
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_GCC
# else
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_C11
# endif
#elif defined(_MSC_VER)
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_MS
#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_GCC
#elif PSNIP_ATOMIC_HAS_FEATURE(c_atomic)
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_CLANG
#elif defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_GCC_SYNC
#elif (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5140)) || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5140))
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_GCC
#elif defined(_OPENMP)
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_OPENMP
#else
# define PSNIP_ATOMIC_NOT_FOUND
# define PSNIP_ATOMIC_IMPL PSNIP_ATOMIC_IMPL_NONE
# warning No atomic implementation found
#endif
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
#if PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_C11
#include <stdatomic.h>
typedef atomic_int_fast64_t psnip_atomic_int64;
typedef atomic_int_fast32_t psnip_atomic_int32;
#define PSNIP_ATOMIC_VAR_INIT(value) ATOMIC_VAR_INIT(value)
#define psnip_atomic_int64_load(object) \
atomic_load(object)
#define psnip_atomic_int64_store(object, desired) \
atomic_store(object, desired)
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
atomic_compare_exchange_strong(object, expected, desired)
#define psnip_atomic_int64_add(object, operand) \
atomic_fetch_add(object, operand)
#define psnip_atomic_int64_sub(object, operand) \
atomic_fetch_sub(object, operand)
#define psnip_atomic_fence() \
atomic_thread_fence(memory_order_seq_cst)
#define PSNIP_ATOMIC_IS_TG
#elif PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_CLANG
#include <stdint.h>
typedef _Atomic psnip_int64_t psnip_atomic_int64;
typedef _Atomic psnip_int32_t psnip_atomic_int32;
#define psnip_atomic_int64_load(object) \
__c11_atomic_load(object, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_store(object, desired) \
__c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
__c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_add(object, operand) \
__c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_sub(object, operand) \
__c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define psnip_atomic_fence() \
__c11_atomic_thread_fence(__ATOMIC_SEQ_CST)
#define PSNIP_ATOMIC_IS_TG
#elif PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_GCC
#include <stdint.h>
#if !defined(__INTEL_COMPILER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && !defined(_OPENMP)
typedef _Atomic psnip_int64_t psnip_atomic_int64;
typedef _Atomic psnip_int32_t psnip_atomic_int32;
#else
typedef psnip_int64_t psnip_atomic_int64;
typedef psnip_int32_t psnip_atomic_int32;
#endif
#define psnip_atomic_int64_load(object) \
__atomic_load_n(object, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_store(object, desired) \
__atomic_store_n(object, desired, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
__atomic_compare_exchange_n(object, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_add(object, operand) \
__atomic_add_fetch(object, operand, __ATOMIC_SEQ_CST)
#define psnip_atomic_int64_sub(object, operand) \
__atomic_sub_fetch(object, operand, __ATOMIC_SEQ_CST)
#define psnip_atomic_fence() \
__atomic_thread_fence(__ATOMIC_SEQ_CST)
#define PSNIP_ATOMIC_IS_TG
#elif PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_GCC_SYNC
#include <stdint.h>
typedef psnip_int64_t psnip_atomic_int64;
typedef psnip_int32_t psnip_atomic_int32;
PSNIP_ATOMIC__FUNCTION
psnip_int64_t
psnip_atomic_int64_load(psnip_atomic_int64* object) {
__sync_synchronize();
return (psnip_int64_t) *object;
}
PSNIP_ATOMIC__FUNCTION
void
psnip_atomic_int64_store(psnip_atomic_int64* object, psnip_int64_t desired) {
*object = desired;
__sync_synchronize();
}
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
__sync_bool_compare_and_swap(object, *(expected), desired)
#define psnip_atomic_int64_add(object, operand) \
__sync_fetch_and_add(object, operand)
#define psnip_atomic_int64_sub(object, operand) \
__sync_fetch_and_sub(object, operand)
PSNIP_ATOMIC__FUNCTION
psnip_int32_t
psnip_atomic_int32_load(psnip_atomic_int32* object) {
__sync_synchronize();
return (psnip_int32_t) *object;
}
PSNIP_ATOMIC__FUNCTION
void
psnip_atomic_int32_store(psnip_atomic_int32* object, psnip_int32_t desired) {
*object = desired;
__sync_synchronize();
}
#define psnip_atomic_int32_compare_exchange(object, expected, desired) \
__sync_bool_compare_and_swap(object, *(expected), desired)
#define psnip_atomic_int32_add(object, operand) \
__sync_fetch_and_add(object, operand)
#define psnip_atomic_int32_sub(object, operand) \
__sync_fetch_and_sub(object, operand)
#define psnip_atomic_fence() \
__sync_synchronize()
#elif PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_MS
#include <Windows.h>
typedef long long volatile psnip_atomic_int64;
typedef long volatile psnip_atomic_int32;
#define psnip_atomic_int32_load(object) \
__pragma(warning(push)) \
__pragma(warning(disable:28112)) \
(*(object)) \
__pragma(warning(pop))
#define psnip_atomic_int32_store(object, desired) \
InterlockedExchange(object, desired)
#define psnip_atomic_int32_compare_exchange(object, expected, desired) \
InterlockedCompareExchange(object, desired, *(expected))
#define psnip_atomic_int32_add(object, operand) \
InterlockedExchangeAdd(object, operand)
#define psnip_atomic_int32_sub(object, operand) \
InterlockedExchangeAdd(object, -(operand))
#define psnip_atomic_int64_load(object) \
__pragma(warning(push)) \
__pragma(warning(disable:28112)) \
(*(object)) \
__pragma(warning(pop))
#define psnip_atomic_int64_store(object, desired) \
InterlockedExchange64(object, desired)
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
InterlockedCompareExchange64(object, desired, *(expected))
#define psnip_atomic_int64_add(object, operand) \
InterlockedExchangeAdd64(object, operand)
#define psnip_atomic_int64_sub(object, operand) \
InterlockedExchangeAdd64(object, -(operand))
#define psnip_atomic_fence() \
MemoryBarrier()
#elif PSNIP_ATOMIC_IMPL == PSNIP_ATOMIC_IMPL_OPENMP
#include <stdint.h>
typedef psnip_int64_t psnip_atomic_int64;
typedef psnip_int32_t psnip_atomic_int32;
PSNIP_ATOMIC__FUNCTION
psnip_int64_t
psnip_atomic_int64_load(psnip_atomic_int64* object) {
psnip_int64_t ret;
#pragma omp critical(psnip_atomic)
ret = *object;
return ret;
}
PSNIP_ATOMIC__FUNCTION
void
psnip_atomic_int64_store(psnip_atomic_int64* object, psnip_int64_t desired) {
#pragma omp critical(psnip_atomic)
*object = desired;
}
PSNIP_ATOMIC__FUNCTION
int
psnip_atomic_int64_compare_exchange_(psnip_atomic_int64* object, psnip_int64_t* expected, psnip_int64_t desired) {
int ret;
#pragma omp critical(psnip_atomic)
ret = (*object == *expected) ? ((*object = desired), 1) : 0;
return ret;
}
#define psnip_atomic_int64_compare_exchange(object, expected, desired) \
psnip_atomic_int64_compare_exchange_(object, expected, desired)
PSNIP_ATOMIC__FUNCTION
psnip_int64_t
psnip_atomic_int64_add(psnip_atomic_int64* object, psnip_int64_t operand) {
int ret;
#pragma omp critical(psnip_atomic)
*object = (ret = *object) + operand;
return ret;
}
PSNIP_ATOMIC__FUNCTION
psnip_int64_t
psnip_atomic_int64_sub(psnip_atomic_int64* object, psnip_int64_t operand) {
int ret;
#pragma omp critical(psnip_atomic)
*object = (ret = *object) - operand;
return ret;
}
PSNIP_ATOMIC__FUNCTION
psnip_int32_t
psnip_atomic_int32_load(psnip_atomic_int32* object) {
psnip_int32_t ret;
#pragma omp critical(psnip_atomic)
ret = *object;
return ret;
}
PSNIP_ATOMIC__FUNCTION
void
psnip_atomic_int32_store(psnip_atomic_int32* object, psnip_int32_t desired) {
#pragma omp critical(psnip_atomic)
*object = desired;
}
PSNIP_ATOMIC__FUNCTION
int
psnip_atomic_int32_compare_exchange_(psnip_atomic_int32* object, psnip_int32_t* expected, psnip_int32_t desired) {
int ret = 1;
#pragma omp critical(psnip_atomic)
ret = (*object == *expected) ? ((*object = desired), 1) : 0;
return ret;
}
#define psnip_atomic_int32_compare_exchange(object, expected, desired) \
psnip_atomic_int32_compare_exchange_(object, expected, desired)
PSNIP_ATOMIC__FUNCTION
psnip_int32_t
psnip_atomic_int32_add(psnip_atomic_int32* object, psnip_int32_t operand) {
int ret;
#pragma omp critical(psnip_atomic)
*object = (ret = *object) + operand;
return ret;
}
PSNIP_ATOMIC__FUNCTION
psnip_int32_t
psnip_atomic_int32_sub(psnip_atomic_int32* object, psnip_int32_t operand) {
int ret;
#pragma omp critical(psnip_atomic)
*object = (ret = *object) - operand;
return ret;
}
PSNIP_ATOMIC__FUNCTION
void
psnip_atomic_fence() {
#pragma omp critical(psnip_atomic)
{ }
}
#endif
#if !defined(PSNIP_ATOMIC_VAR_INIT)
# define PSNIP_ATOMIC_VAR_INIT(value) (value)
#endif
/* Most compilers have type-generic atomic implementations. */
#if defined(PSNIP_ATOMIC_IS_TG)
#define psnip_atomic_int32_load(object) \
psnip_atomic_int64_load(object)
#define psnip_atomic_int32_store(object, desired) \
psnip_atomic_int64_store(object, desired)
#define psnip_atomic_int32_compare_exchange(object, expected, desired) \
psnip_atomic_int64_compare_exchange(object, expected, desired)
#define psnip_atomic_int32_add(object, operand) \
psnip_atomic_int64_add(object, operand)
#define psnip_atomic_int32_sub(object, operand) \
psnip_atomic_int64_sub(object, operand)
#endif /* defined(PSNIP_ATOMIC_IS_TG) */
#endif /* !defined(PSNIP_ATOMIC_NOT_FOUND) */
#endif /* defined(PSNIP_ATOMIC_H) */
================================================
FILE: avx-turbo.cpp
================================================
/*
* avx-turbo.cpp
*/
#include "args.hxx"
#include "cpu.h"
#include "cpuid.hpp"
#include "msr-access.h"
#include "stats.hpp"
#include "tsc-support.hpp"
#include "table.hpp"
#include "util.hpp"
#include <array>
#include <atomic>
#include <deque>
#include <cassert>
#include <cstdlib>
#include <chrono>
#include <cinttypes>
#include <exception>
#include <limits>
#include <set>
#include <functional>
#include <thread>
#include <vector>
#include <error.h>
#include <err.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#define MSR_IA32_MPERF 0x000000e7
#define MSR_IA32_APERF 0x000000e8
using std::uint64_t;
using namespace std::chrono;
using namespace Stats;
typedef void (cal_f)(uint64_t iters);
enum ISA {
BASE = 1 << 0,
AVX2 = 1 << 1,
AVX512F = 1 << 2, // note: does not imply VL, so xmm and ymm may not be available
AVX512VL = 1 << 3, // note: does not imply F, although i don't know any CPU with VL but not F
AVX512CD = 1 << 4,
AVX512BW = 1 << 5,
};
struct test_func {
// function pointer to the test function
cal_f* func;
const char* id;
const char* description;
ISA isa;
};
#define FUNCS_X(x) \
x(pause_only , "pause instruction" , BASE) \
x(ucomis_clean , "scalar ucomis (w/ vzeroupper)" , AVX2) \
x(ucomis_dirty , "scalar ucomis (no vzeroupper)" , AVX2) \
\
/* iadd */ \
x(scalar_iadd , "Scalar integer adds" , BASE) \
x(avx128_iadd , "128-bit integer serial adds" , AVX2 ) \
x(avx256_iadd , "256-bit integer serial adds" , AVX2 ) \
x(avx512_iadd , "512-bit integer serial adds" , AVX512F) \
\
x(avx128_iadd16 , "128-bit integer serial adds zmm16", AVX512VL) \
x(avx256_iadd16 , "256-bit integer serial adds zmm16", AVX512VL) \
x(avx512_iadd16 , "512-bit integer serial adds zmm16", AVX512F) \
\
/* iadd throughput */ \
x(avx128_iadd_t , "128-bit integer parallel adds" , AVX2 ) \
x(avx256_iadd_t , "256-bit integer parallel adds" , AVX2 ) \
\
/* zeroing xor */ \
x(avx128_xor_zero , "128-bit zeroing xor" , AVX2 ) \
x(avx256_xor_zero , "256-bit zeroing xor" , AVX2 ) \
x(avx512_xor_zero , "512-bit zeroing xord" , AVX512F) \
\
/* reg-reg mov */ \
x(avx128_mov_sparse , "128-bit reg-reg mov" , AVX2) \
x(avx256_mov_sparse , "256-bit reg-reg mov" , AVX2 ) \
x(avx512_mov_sparse , "512-bit reg-reg mov" , AVX512F) \
\
/* merge */ \
x(avx128_merge_sparse , "128-bit reg-reg merge mov" , AVX512VL) \
x(avx256_merge_sparse , "256-bit reg-reg merge mov" , AVX512VL) \
x(avx512_merge_sparse , "512-bit reg-reg merge mov" , AVX512F) \
\
/* variable shift latency */ \
x(avx128_vshift , "128-bit variable shift (vpsrlvd)", AVX2 ) \
x(avx256_vshift , "256-bit variable shift (vpsrlvd)", AVX2 ) \
x(avx512_vshift , "512-bit variable shift (vpsrlvd)", AVX512F) \
/* variable shift throughput */ \
x(avx128_vshift_t , "128-bit variable shift (vpsrlvd)", AVX2 ) \
x(avx256_vshift_t , "256-bit variable shift (vpsrlvd)", AVX2 ) \
x(avx512_vshift_t , "512-bit variable shift (vpsrlvd)", AVX512F) \
\
/* vplzcntd latency */ \
x(avx128_vlzcnt , "128-bit lzcnt (vplzcntd)", AVX512CD | AVX512VL) \
x(avx256_vlzcnt , "256-bit lzcnt (vplzcntd)", AVX512CD | AVX512VL) \
x(avx512_vlzcnt , "512-bit lzcnt (vplzcntd)", AVX512CD) \
/* vplzcntd throughput */ \
x(avx128_vlzcnt_t , "128-bit lzcnt (vplzcntd)", AVX512CD | AVX512VL) \
x(avx256_vlzcnt_t , "256-bit lzcnt (vplzcntd)", AVX512CD | AVX512VL) \
x(avx512_vlzcnt_t , "512-bit lzcnt (vplzcntd)", AVX512CD) \
\
x(avx128_imul , "128-bit integer muls (vpmuldq)" , AVX2 ) \
x(avx256_imul , "256-bit integer muls (vpmuldq)" , AVX2 ) \
x(avx512_imul , "512-bit integer muls (vpmuldq)" , AVX512F) \
\
/* fma */ \
x(avx128_fma_sparse , "128-bit 64-bit sparse FMAs" , AVX2 ) \
x(avx256_fma_sparse , "256-bit 64-bit sparse FMAs" , AVX2 ) \
x(avx512_fma_sparse , "512-bit 64-bit sparse FMAs" , AVX512F) \
x(avx128_fma , "128-bit serial DP FMAs" , AVX2 ) \
x(avx256_fma , "256-bit serial DP FMAs" , AVX2 ) \
x(avx512_fma , "512-bit serial DP FMAs" , AVX512F) \
x(avx128_fma_t , "128-bit parallel DP FMAs" , AVX2 ) \
x(avx256_fma_t , "256-bit parallel DP FMAs" , AVX2 ) \
x(avx512_fma_t , "512-bit parallel DP FMAs" , AVX512F) \
\
x(avx512_vpermw , "512-bit serial WORD permute" , AVX512BW) \
x(avx512_vpermw_t , "512-bit parallel WORD permute" , AVX512BW) \
x(avx512_vpermd , "512-bit serial DWORD permute" , AVX512F) \
x(avx512_vpermd_t , "512-bit parallel DWORD permute" , AVX512F) \
#define DECLARE(f,...) cal_f f;
extern "C" {
// functions declared in asm-methods.asm
FUNCS_X(DECLARE);
// misc helpers
void zeroupper_asm();
static bool zeroupper_allowed;
void zeroupper() {
if (zeroupper_allowed) zeroupper_asm();
}
}
#define MAKE_STRUCT(f, d, i) { f, #f, d, (ISA)(i) },
const test_func ALL_FUNCS[] = {
FUNCS_X(MAKE_STRUCT)
};
void pin_to_cpu(int cpu) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (sched_setaffinity(0, sizeof(cpuset), &cpuset) == -1) {
error(EXIT_FAILURE, errno, "could not pin to CPU %d", cpu);
}
}
/** args */
args::ArgumentParser parser{"avx-turbo: Determine AVX2 and AVX-512 downclocking behavior"};
args::HelpFlag help{parser, "help", "Display this help menu", {'h', "help"}};
args::Flag arg_force_tsc_cal{parser, "force-tsc-calibrate",
"Force manual TSC calibration loop, even if cpuid TSC Hz is available", {"force-tsc-calibrate"}};
args::Flag arg_no_pin{parser, "no-pin",
"Don't try to pin threads to CPU - gives worse results but works around affinity issues on TravisCI", {"no-pin"}};
args::Flag arg_verbose{parser, "verbose", "Output more info", {"verbose"}};
args::Flag arg_nobarrier{parser, "no-barrier", "Don't sync up threads before each test (debugging only)", {"no-barrier"}};
args::Flag arg_list{parser, "list", "List the available tests and their descriptions", {"list"}};
args::Flag arg_hyperthreads{parser, "allow-hyperthreads", "By default we try to filter down the available cpus to include only physical cores, but "
"with this option we'll use all logical cores meaning you'll run two tests on cores with hyperthreading", {"allow-hyperthreads"}};
args::Flag arg_dirty{parser, "dirty-upper", "AVX-512 only: the 512-bit zmm15 register is dirtied befor each test",
{"dirty-upper"}};
args::Flag arg_dirty16{parser, "dirty-upper", "AVX-512 only: the 512-bit zmm16 register is dirtied befor each test",
{"dirty-upper16"}};
args::ValueFlag<std::string> arg_focus{parser, "TEST-ID", "Run only the specified test (by ID)", {"test"}};
args::ValueFlag<std::string> arg_spec{parser, "SPEC", "Run a specific type of test specified by a specification string", {"spec"}};
args::ValueFlag<size_t> arg_iters{parser, "ITERS", "Run the test loop ITERS times (default 100000)", {"iters"}, 100000};
args::ValueFlag<int> arg_min_threads{parser, "MIN", "The minimum number of threads to use", {"min-threads"}, 1};
args::ValueFlag<int> arg_max_threads{parser, "MAX", "The maximum number of threads to use", {"max-threads"}};
args::ValueFlag<int> arg_num_cpus{parser, "CPUS", "Override number of available CPUs", {"num-cpus"}};
args::ValueFlag<uint64_t> arg_warm_ms{parser, "MILLISECONDS", "Warmup milliseconds for each thread after pinning (default 100)", {"warmup-ms"}, 100};
bool verbose;
template <typename CHRONO_CLOCK>
struct StdClock {
using now_t = decltype(CHRONO_CLOCK::now());
using delta_t = typename CHRONO_CLOCK::duration;
static now_t now() {
return CHRONO_CLOCK::now();
}
/* accept the result of subtraction of durations and convert to nanos */
static uint64_t to_nanos(typename CHRONO_CLOCK::duration d) {
return duration_cast<std::chrono::nanoseconds>(d).count();
}
};
struct RdtscClock {
using now_t = uint64_t;
using delta_t = uint64_t;
static now_t now() {
_mm_lfence();
now_t ret = rdtsc();
_mm_lfence();
return ret;
}
/* accept the result of subtraction of durations and convert to nanos */
static uint64_t to_nanos(now_t diff) {
static double tsc_to_nanos = 1000000000.0 / tsc_freq();
return diff * tsc_to_nanos;
}
static uint64_t tsc_freq() {
static uint64_t freq = get_tsc_freq(arg_force_tsc_cal);
return freq;
}
};
/**
* We pass an outer_clock to run_test which times outside the iteration of the innermost loop (i.e.,
* it times around the loop that runs TRIES times), start should reset the state unless you want to
* time warmup iterations.
*/
struct outer_timer {
virtual void start() = 0;
virtual void stop() = 0;
virtual ~outer_timer() {}
};
struct dummy_outer : outer_timer {
static dummy_outer dummy;
virtual void start() override {};
virtual void stop() override {};
};
dummy_outer dummy_outer::dummy{};
/** lets you determine the actual frequency over any interval using the free-running APERF and MPERF counters */
struct aperf_ghz : outer_timer {
uint64_t mperf_value, aperf_value, tsc_value;
enum {
STARTED, STOPPED
} state;
aperf_ghz() : mperf_value(0), aperf_value(0), tsc_value(0), state(STOPPED) {}
static uint64_t mperf() {
return read(MSR_IA32_MPERF);
}
static uint64_t aperf() {
return read(MSR_IA32_APERF);
}
static uint64_t read(uint32_t msr) {
uint64_t value = -1;
int res = read_msr_cur_cpu(msr, &value);
assert(res == 0);
return value;
}
/**
* Return true iff APERF and MPERF MSR reads appear to work
*/
static bool is_supported() {
uint64_t dummy;
return read_msr_cur_cpu(MSR_IA32_MPERF, &dummy) == 0
&& read_msr_cur_cpu(MSR_IA32_APERF, &dummy) == 0;
}
virtual void start() override {
assert(state == STOPPED);
state = STARTED;
mperf_value = mperf();
aperf_value = aperf();
tsc_value = rdtsc();
// printf("started timer m: %lu\n", mperf_value);
// printf("started timer a: %lu\n", aperf_value);
};
virtual void stop() override {
assert(state == STARTED);
mperf_value = mperf() - mperf_value;
aperf_value = aperf() - aperf_value;
tsc_value = rdtsc() - tsc_value;
state = STOPPED;
// printf("stopped timer m: %lu (delta)\n", mperf_value);
// printf("stopped timer a: %lu (delta)\n", aperf_value);
};
/** aperf / mperf ratio */
double am_ratio() {
assert(state == STOPPED);
assert(mperf_value != 0 && aperf_value != 0);
// printf("timer ratio m: %lu (delta)\n", mperf_value);
// printf("timer ratio a: %lu (delta)\n", aperf_value);
return (double)aperf_value / mperf_value;
}
/** mperf / tsc ratio, i.e., the % of the time the core was unhalted */
double mt_ratio() {
assert(state == STOPPED);
assert(mperf_value != 0 && tsc_value != 0);
// printf("timer ratio m: %lu (delta)\n", mperf_value);
// printf("timer ratio a: %lu (delta)\n", aperf_value);
return (double)mperf_value / tsc_value;
}
};
/*
* The result of the run_test method, with only the stuff
* that can be calculated from within that method.
*/
struct inner_result {
/* calculated Mops value */
double mops;
uint64_t ostart_ts, oend_ts;
uint64_t istart_ts, iend_ts; // start and end timestamps for the "critical" benchmark portion
};
/*
* Calculate the frequency of the CPU based on timing a tight loop that we expect to
* take one iteration per cycle.
*
* ITERS is the base number of iterations to use: the calibration routine is actually
* run twice, once with ITERS iterations and once with 2*ITERS, and a delta is used to
* remove measurement overhead.
*/
struct hot_barrier {
size_t break_count;
std::atomic<size_t> current;
hot_barrier(size_t count) : break_count(count), current{0} {}
/* increment the arrived count of the barrier (do this once per thread generally) */
void increment() {
current++;
}
/* return true if all the threads have arrived, never blocks */
bool is_broken() {
return current.load() == break_count;
}
/* increment and hot spin on the waiter count until it hits the break point, returns the spin count in case you care */
long wait() {
increment();
long count = 0;
while (!is_broken()) {
count++;
}
return count;
}
};
// dirties zmm15 upper bits
extern "C" void dirty_it();
// dirties zmm15 upper bits
extern "C" void dirty_it16();
template <typename CLOCK, size_t TRIES = 101, size_t WARMUP = 3>
inner_result run_test(cal_f* func, size_t iters, outer_timer& outer, hot_barrier *barrier) {
assert(iters % 100 == 0);
std::array<typename CLOCK::delta_t, TRIES> results;
inner_result result;
if (arg_dirty) {
dirty_it();
}
if (arg_dirty16) {
dirty_it16();
}
result.ostart_ts = RdtscClock::now();
for (size_t w = 0; w < WARMUP + 1; w++) {
result.istart_ts = RdtscClock::now();
outer.start();
for (size_t r = 0; r < TRIES; r++) {
auto t0 = CLOCK::now();
func(iters);
auto t1 = CLOCK::now();
func(iters * 2);
auto t2 = CLOCK::now();
results[r] = (t2 - t1) - (t1 - t0);
}
outer.stop();
result.iend_ts = RdtscClock::now();
}
for (barrier->increment(); !barrier->is_broken();) {
func(iters);
}
result.oend_ts = RdtscClock::now();
std::array<uint64_t, TRIES> nanos = {};
std::transform(results.begin(), results.end(), nanos.begin(), CLOCK::to_nanos);
DescriptiveStats stats = get_stats(nanos.begin(), nanos.end());
result.mops = ((double)iters / stats.getMedian());
return result;
}
ISA get_isas() {
int ret = BASE;
ret |= psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX2 ) ? AVX2 : 0;
ret |= psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX512F ) ? AVX512F : 0;
ret |= psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX512VL) ? AVX512VL : 0;
ret |= psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX512CD) ? AVX512CD : 0;
ret |= psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX512BW) ? AVX512BW : 0;
return (ISA)ret;
}
bool should_run(const test_func& t, ISA isas_supported) {
return (t.isa & isas_supported) == t.isa;
}
/*
* A test_spec contains the information needed to run one test. It is composed of
* a list of test_funcs, which should be run in parallel on separate threads.
*/
struct test_spec {
std::string name;
std::string description;
std::vector<test_func> thread_funcs;
test_spec(std::string name, std::string description) : name{name}, description{description} {}
/** how many threads/funcs in this test */
size_t count() const { return thread_funcs.size(); }
std::string to_string() const {
std::string ret;
for (auto& t : thread_funcs) {
ret += t.id;
ret += ',';
}
return ret;
}
};
/* find the test that exactly matches the given ID or return nullptr if not found */
const test_func *find_one_test(const std::string& id) {
for (const auto& t : ALL_FUNCS) {
if (id == t.id) {
return &t;
}
}
return nullptr;
}
/**
* If the user didn't specify any particular test spec, just create for every thread count
* value T and runnable func, a spec with T copies of func.
*/
std::vector<test_spec> make_default_tests(ISA isas_supported, std::vector<int> cpus) {
std::vector<test_spec> ret;
size_t maxcpus;
if (arg_max_threads) {
auto max = arg_max_threads.Get();
if (max > (int)cpus.size()) {
printf("WARNING: can't run the requested number of threads (%d) because there are only %d available logical CPUs.\n",
max, (int)cpus.size());
maxcpus = (int)cpus.size();
} else {
maxcpus = max;
}
} else {
maxcpus = cpus.size();
}
printf("Will test up to %lu CPUs\n", maxcpus);
auto try_add = [&ret](const test_func& t, size_t thread_count) {
test_spec spec(t.id, t.description);
spec.thread_funcs.resize(thread_count, t); // fill with thread_count copies of t
ret.push_back(std::move(spec));
};
std::vector<test_func> funcs; // the selected test functions
if (arg_focus) {
for (auto& focus : split(arg_focus.Get(), ",")) {
auto t = find_one_test(focus);
if (!t) {
printf("WARNING: Can't find specified test: %s\n", focus.c_str());
} else {
funcs.push_back(*t);
}
}
} else {
funcs.insert(funcs.begin(), std::begin(ALL_FUNCS), std::end(ALL_FUNCS));
}
for (size_t thread_count = arg_min_threads.Get(); thread_count <= maxcpus; thread_count++) {
for (const auto& t : funcs) {
if (should_run(t, isas_supported)) {
try_add(t, thread_count);
}
}
}
return ret;
}
std::vector<test_spec> make_from_spec(ISA, std::vector<int> cpus) {
std::string str = arg_spec.Get();
if (verbose) printf("Making tests from spec string: %s\n", str.c_str());
test_spec spec{str, "<multiple descriptions>"};
for (auto& elem : split(str,",")) {
if (verbose) printf("Elem: %s\n", elem.c_str());
std::vector<std::string> halves = split(elem,"/");
assert(halves.size() > 0);
if (halves.size() > 2) {
throw std::runtime_error(std::string("bad spec syntax in element: '" + elem + "'"));
}
int count = (halves.size() == 1 ? 1 : std::atoi(halves[1].c_str()));
const test_func* test = find_one_test(halves[0]);
if (!test) {
throw std::runtime_error("couldn't find test: '" + halves[0] + "'");
}
spec.thread_funcs.insert(spec.thread_funcs.end(), count, *test);
}
if (spec.count() > cpus.size()) {
printf("ERROR: this spec requires %d CPUs but only %d are available.\n", (int)spec.count(), (int)cpus.size());
exit(EXIT_FAILURE);
}
return {spec};
}
std::vector<test_spec> filter_tests(ISA isas_supported, std::vector<int> cpus) {
if (!arg_spec) {
return make_default_tests(isas_supported, cpus);
} else {
return make_from_spec(isas_supported, cpus);
}
}
struct result {
static constexpr double nan = std::numeric_limits<double>::quiet_NaN();
inner_result inner;
uint64_t start_ts; // start timestamp
uint64_t end_ts; // end timestamp
/* optional stuff associated with outer_timer */
double aperf_am = nan;
double aperf_mt = nan;
};
struct result_holder {
const test_spec* spec;
std::vector<result> results; // will have spec.count() elements
result_holder(const test_spec* spec) : spec(spec) {}
/** calculate the overlap ratio based on the start/end timestamps */
double get_overlap1() const {
std::vector<std::pair<uint64_t, uint64_t>> ranges = transformv(results, [](const result& r){ return std::make_pair(r.start_ts, r.end_ts);} );
return conc_ratio(ranges.begin(), ranges.end());
}
/** calculate the overlap ratio based on the start/end timestamps */
double get_overlap2() const {
std::vector<std::pair<uint64_t, uint64_t>> ranges = transformv(results, [](const result& r){ return std::make_pair(r.inner.istart_ts, r.inner.iend_ts);} );
return conc_ratio(ranges.begin(), ranges.end());
}
/** calculate the inner overlap ratio based on the start/end timestamps */
double get_overlap3() const {
auto orange = transformv(results, [](const result& r){ return std::make_pair(r.inner.ostart_ts, r.inner.oend_ts);} );
auto irange = transformv(results, [](const result& r){ return std::make_pair(r.inner.istart_ts, r.inner.iend_ts);} );
return nconc_ratio(orange.begin(), orange.end(), irange.begin(), irange.end());
}
};
struct warmup {
uint64_t millis;
warmup(uint64_t millis) : millis{millis} {}
long warm() {
int64_t start = (int64_t)RdtscClock::now();
long iters = 0;
while (RdtscClock::to_nanos(RdtscClock::now() - start) < 1000000u * millis) {
iters++;
}
return iters;
}
};
struct test_thread {
size_t id;
hot_barrier* start_barrier;
hot_barrier* stop_barrier;
/* output */
result res;
/* input */
const test_func* test;
size_t iters;
bool use_aperf;
std::thread thread;
test_thread(size_t id, hot_barrier& start_barrier, hot_barrier& stop_barrier, const test_func *test, size_t iters, bool use_aperf) :
id{id}, start_barrier{&start_barrier}, stop_barrier{&stop_barrier}, test{test},
iters{iters}, use_aperf{use_aperf}, thread{std::ref(*this)}
{
// if (verbose) printf("Constructed test in thread %lu, this = %p\n", id, this);
}
test_thread(const test_thread&) = delete;
test_thread(test_thread&&) = delete;
void operator=(const test_thread&) = delete;
void operator()() {
// if (verbose) printf("Running test in thread %lu, this = %p\n", id, this);
if (!arg_no_pin) {
pin_to_cpu(id);
}
aperf_ghz aperf_timer;
outer_timer& outer = use_aperf ? static_cast<outer_timer&>(aperf_timer) : dummy_outer::dummy;
warmup w{arg_warm_ms.Get()};
long warms = w.warm();
if (verbose) printf("[%2lu] Warmup iters %lu\n", id, warms);
if (!arg_nobarrier) {
long count = start_barrier->wait();
if (verbose) printf("[%2lu] Thread loop count: %ld\n", id, count);
}
res.start_ts = RdtscClock::now();
res.inner = run_test<RdtscClock>(test->func, iters, outer, stop_barrier);
res.end_ts = RdtscClock::now();
res.aperf_am = use_aperf ? aperf_timer.am_ratio() : 0.0;
res.aperf_mt = use_aperf ? aperf_timer.mt_ratio() : 0.0;
}
};
template <typename E>
std::string result_string(const std::vector<result>& results, const char* format, E e) {
std::string s;
for (const auto& result : results) {
if (!s.empty()) s += ", ";
s += table::string_format(format, e(result));
}
return s;
}
void report_results(const std::vector<result_holder>& results_list, bool use_aperf) {
// report
table::Table table;
table.setColColumnSeparator(" | ");
auto& header = table.newRow();
using table::ColInfo;
auto adder = [&header, &table](const char* s, ColInfo::Justification just = ColInfo::LEFT) {
header.add(s);
table.colInfo(header.size() - 1).justify = just;
};
adder("Cores");
adder("ID");
adder("Description");
// adder("OVRLP1", ColInfo::RIGHT);
// adder("OVRLP2", ColInfo::RIGHT);
adder("OVRLP3", ColInfo::RIGHT);
adder("Mops", ColInfo::RIGHT);
if (use_aperf) {
adder("A/M-ratio", ColInfo::RIGHT);
adder("A/M-MHz", ColInfo::RIGHT);
adder("M/tsc-ratio", ColInfo::RIGHT);
}
for (const result_holder& holder : results_list) {
auto spec = holder.spec;
auto &row = table.newRow()
.add(spec->count())
.add(spec->name)
.add(spec->description)
// .addf("%5.3f", holder.get_overlap1())
// .addf("%5.3f", holder.get_overlap2())
.addf("%5.3f", holder.get_overlap3());
auto& results = holder.results;
row.add(result_string(results, "%5.0f", [](const result& r){ return r.inner.mops * 1000; }));
if (use_aperf) {
row.add(result_string(results, "%4.2f", [](const result& r){ return r.aperf_am; }));
row.add(result_string(results, "%.0f", [](const result& r){ return r.aperf_am / 1000000.0 * RdtscClock::tsc_freq(); }));
row.add(result_string(results, "%4.2f", [](const result& r){ return r.aperf_mt; }));
}
}
printf("%s\n", table.str().c_str());
}
void list_tests() {
table::Table table;
table.newRow().add("ID").add("Description");
for (auto& t : ALL_FUNCS) {
table.newRow().add(t.id).add(t.description);
}
printf("Available tests:\n\n%s\n", table.str().c_str());
}
std::vector<int> get_cpus() {
if (arg_num_cpus) {
auto cpu_num = arg_num_cpus.Get();
std::vector<int> ret;
for (int cpu = 0; cpu < cpu_num; ++cpu) {
ret.push_back(cpu);
}
return ret;
}
cpu_set_t cpu_set;
if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set)) {
err(EXIT_FAILURE, "failed while getting cpu affinity");
}
std::vector<int> ret;
for (int cpu = 0; cpu < CPU_SETSIZE; cpu++) {
if (CPU_ISSET(cpu, &cpu_set)) {
ret.push_back(cpu);
}
}
return ret;
}
/* try to filter the CPU list to return only physical CPUs */
std::vector<int> filter_cpus(std::vector<int> cpus) {
int shift = get_smt_shift();
if (shift == -1) {
printf("Can't use cpuid leaf 0xb to filter out hyperthreads, CPU too old or AMD\n");
return cpus;
}
cpu_set_t original_set;
if (sched_getaffinity(0, sizeof(original_set), &original_set)) {
err(EXIT_FAILURE, "failed while getting cpu affinity");
}
std::vector<int> filtered_cpus;
std::set<uint32_t> coreid_set;
for (int cpu : cpus) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (sched_setaffinity(0, sizeof(cpu_set_t), &cpuset)) {
err(EXIT_FAILURE, "failed to sched_setaffinity in filter_cpus");
}
cpuid_result leafb = cpuid(0xb);
uint32_t apicid = leafb.edx, coreid = apicid >> shift;
if (verbose) printf("cpu %d has x2apic ID %u, coreid %u\n", cpu, apicid, coreid);
if (coreid_set.insert(coreid).second) {
filtered_cpus.push_back(cpu);
}
}
// restore original affinity
sched_setaffinity(0, sizeof(cpu_set_t), &original_set);
return filtered_cpus;
}
int main(int argc, char** argv) {
try {
parser.ParseCLI(argc, argv);
if (arg_iters.Get() % 100 != 0) {
printf("ITERS must be a multiple of 100\n");
exit(EXIT_FAILURE);
}
} catch (args::Help& help) {
printf("%s\n", parser.Help().c_str());
exit(EXIT_SUCCESS);
} catch (const args::ParseError& e) {
printf("ERROR while parsing arguments: %s\n", e.what());
printf("\nUsage:\n%s\n", parser.Help().c_str());
exit(EXIT_FAILURE);
}
if (arg_list) {
list_tests();
exit(EXIT_SUCCESS);
}
verbose = arg_verbose;
bool is_root = (geteuid() == 0);
bool use_aperf = aperf_ghz::is_supported();
printf("CPUID highest leaf : [%2xh]\n", cpuid_highest_leaf());
printf("Running as root : [%s]\n", is_root ? "YES" : "NO ");
printf("MSR reads supported : [%s]\n", use_aperf ? "YES" : "NO ");
printf("CPU pinning enabled : [%s]\n", !arg_no_pin ? "YES" : "NO ");
ISA isas_supported = get_isas();
zeroupper_allowed = isas_supported & AVX2;
printf("CPU supports zeroupper: [%s]\n", zeroupper_allowed ? "YES" : "NO ");
printf("CPU supports AVX2 : [%s]\n", isas_supported & AVX2 ? "YES" : "NO ");
printf("CPU supports AVX-512F : [%s]\n", isas_supported & AVX512F ? "YES" : "NO ");
printf("CPU supports AVX-512VL: [%s]\n", isas_supported & AVX512VL ? "YES" : "NO ");
printf("CPU supports AVX-512BW: [%s]\n", isas_supported & AVX512BW ? "YES" : "NO ");
printf("CPU supports AVX-512CD: [%s]\n", isas_supported & AVX512CD ? "YES" : "NO ");
printf("tsc_freq = %.1f MHz (%s)\n", RdtscClock::tsc_freq() / 1000000.0, get_tsc_cal_info(arg_force_tsc_cal));
std::vector<int> cpus = get_cpus();
printf("CPU brand string: %s\n", get_brand_string().c_str());
printf("%lu available CPUs: [%s]\n", cpus.size(), join(cpus, ", ").c_str());
if (!arg_hyperthreads) {
cpus = filter_cpus(cpus);
printf("%lu physical cores: [%s]\n", cpus.size(), join(cpus, ", ").c_str());
}
if (arg_dirty && !(isas_supported & AVX512VL)) {
printf("ERROR: --dirty-upper only supported on AVX-512 hardware\n");
exit(EXIT_FAILURE);
}
auto iters = arg_iters.Get();
zeroupper();
auto specs = filter_tests(isas_supported, cpus);
size_t last_thread_count = -1u;
std::vector<result_holder> results_list;
for (auto& spec : specs) {
// if we changed the number of threads, spit out the accumulated output
if (last_thread_count != -1u && last_thread_count != spec.count()) {
// time to print results
report_results(results_list, use_aperf);
results_list.clear();
}
last_thread_count = spec.count();
assert(!spec.thread_funcs.empty());
if (verbose) printf("Running test spec: %s\n", spec.to_string().c_str());
// run
std::deque<test_thread> threads;
hot_barrier start{spec.count()}, stop{spec.count()};
for (auto& test : spec.thread_funcs) {
threads.emplace_back(threads.size(), start, stop, &test, iters, use_aperf);
}
results_list.emplace_back(&spec);
for (auto& t : threads) {
t.thread.join();
results_list.back().results.push_back(t.res);
}
}
report_results(results_list, use_aperf);
return EXIT_SUCCESS;
}
================================================
FILE: check-uarch.sh
================================================
#!/bin/bash
set -e
# runs Intel SDE to check that ./avx-turbo works for every arch
all_arch=( \
p4p \
mrm \
pnr \
nhm \
wsm \
snb \
ivb \
hsw \
bdw \
slt \
slm \
glm \
tnt \
skl \
clx \
skx \
cnl \
icl \
icx \
knl \
knm \
future \
)
for arch in "${all_arch[@]}"; do
echo "Testing arch=$arch with SDE"
sde64 -${arch} -- ./avx-turbo --max-threads=1
done
================================================
FILE: config.mk
================================================
-include local.mk
# set DEBUG to 1 to enable various debugging checks
DEBUG ?= 0
# The assembler to use. Defaults to nasm, but can also be set to yasm which has better
# debug info handling.
ASM ?= ./nasm-2.13.03/nasm
ifeq ($(DEBUG),1)
O_LEVEL ?= -O0
NASM_DEBUG ?= 1
else
O_LEVEL ?= -O2
NASM_DEBUG ?= 0
endif
================================================
FILE: cpu.c
================================================
/* CPU Information (v1)
* Portable Snippets - https://gitub.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*/
#include "cpu.h"
#include "once.h"
#include <assert.h>
#if defined(_WIN32)
# include <Windows.h>
# define PSNIP_CPU__IMPL_WIN32
#elif defined(unix) || defined(__unix__) || defined(__unix)
# include <unistd.h>
# if defined(_SC_NPROCESSORS_ONLN) || defined(_SC_NPROC_ONLN)
# define PSNIP_CPU__IMPL_SYSCONF
# else
# include <sys/sysctl.h>
# endif
#endif
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
# if defined(_MSC_VER)
static void psnip_cpu_getid(int func, int* data) {
__cpuid(data, func);
}
# else
static void psnip_cpu_getid(int func, int* data) {
__asm__ ("cpuid"
: "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3])
: "0" (func), "2" (0));
}
# endif
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM64)
# if (defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 16)))
# define PSNIP_CPU__IMPL_GETAUXVAL
# include <sys/auxv.h>
# endif
#endif
static psnip_once psnip_cpu_once = PSNIP_ONCE_INIT;
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
static unsigned int psnip_cpuinfo[8 * 4] = { 0, };
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM_64)
static unsigned long psnip_cpuinfo[2] = { 0, };
#endif
static void psnip_cpu_init(void) {
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
int i;
for (i = 0 ; i < 8 ; i++) {
psnip_cpu_getid(i, (int*) &(psnip_cpuinfo[i * 4]));
}
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM_64)
psnip_cpuinfo[0] = getauxval (AT_HWCAP);
psnip_cpuinfo[1] = getauxval (AT_HWCAP2);
#endif
}
int
psnip_cpu_feature_check (enum PSnipCPUFeature feature) {
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
unsigned int i, r, b;
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM_64)
unsigned long b, i;
#endif
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
if ((feature & PSNIP_CPU_FEATURE_CPU_MASK) != PSNIP_CPU_FEATURE_X86)
return 0;
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM_64)
if ((feature & PSNIP_CPU_FEATURE_CPU_MASK) != PSNIP_CPU_FEATURE_ARM)
return 0;
#else
return 0;
#endif
feature &= (enum PSnipCPUFeature) ~PSNIP_CPU_FEATURE_CPU_MASK;
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4152)
#endif
psnip_once_call (&psnip_cpu_once, psnip_cpu_init);
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(PSNIP_CPU_ARCH_X86) || defined(PSNIP_CPU_ARCH_X86_64)
i = (feature >> 16) & 0xff;
r = (feature >> 8) & 0xff;
b = (feature ) & 0xff;
if (i > 7 || r > 3 || b > 31)
return 0;
return (psnip_cpuinfo[(i * 4) + r] >> b) & 1;
#elif defined(PSNIP_CPU_ARCH_ARM) || defined(PSNIP_CPU_ARCH_ARM_64)
b = 1 << ((feature & 0xff) - 1);
i = psnip_cpuinfo[(feature >> 0x08) & 0xff];
return (psnip_cpuinfo[(feature >> 0x08) & 0xff] & b) == b;
#endif
}
int
psnip_cpu_feature_check_many (enum PSnipCPUFeature* feature) {
int n;
for (n = 0 ; feature[n] != PSNIP_CPU_FEATURE_NONE ; n++)
if (!psnip_cpu_feature_check(feature[n]))
return 0;
return 1;
}
int
psnip_cpu_count (void) {
static int count = 0;
int c;
#if defined(_WIN32)
DWORD_PTR lpProcessAffinityMask;
DWORD_PTR lpSystemAffinityMask;
int i;
#elif defined(PSNIP_CPU__IMPL_SYSCONF) && defined(HW_NCPU)
int mib[2];
size_t len;
#endif
if (count != 0)
return count;
#if defined(_WIN32)
if (!GetProcessAffinityMask(GetCurrentProcess(), &lpProcessAffinityMask, &lpSystemAffinityMask)) {
c = -1;
} else {
c = 0;
for (i = 0 ; lpProcessAffinityMask != 0 ; lpProcessAffinityMask >>= 1)
c += lpProcessAffinityMask & 1;
}
#elif defined(_SC_NPROCESSORS_ONLN)
c = sysconf (_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROC_ONLN)
c = sysconf (_SC_NPROC_ONLN);
#elif defined(_hpux)
c = mpctl(MPC_GETNUMSPUS, NULL, NULL);
#elif defined(HW_NCPU)
c = 0;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
len = sizeof(c);
sysctl (mib, 2, &c, &len, NULL, 0);
#endif
count = (c > 0) ? c : -1;
return count;
}
================================================
FILE: cpu.h
================================================
/* CPU Information (v1)
* Portable Snippets - https://gitub.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*/
#if !defined(PSNIP_CPU__H)
#define PSNIP_CPU__H
#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
# define PSNIP_CPU_ARCH_X86_64
#elif defined(__i686__) || defined(__i586__) || defined(__i486__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || defined(__THW_INTEL__)
# define PSNIP_CPU_ARCH_X86
#elif defined(__arm__) || defined(_M_ARM)
# define PSNIP_CPU_ARCH_ARM
#elif defined(__aarch64__)
# define PSNIP_CPU_ARCH_ARM64
#endif
#if defined(__cplusplus)
extern "C" {
#endif
enum PSnipCPUFeature {
PSNIP_CPU_FEATURE_NONE = 0,
PSNIP_CPU_FEATURE_CPU_MASK = 0x1f000000,
PSNIP_CPU_FEATURE_X86 = 0x01000000,
PSNIP_CPU_FEATURE_ARM = 0x04000000,
/* x86 CPU features are constructed as:
*
* (PSNIP_CPU_FEATURE_X86 | (eax << 16) | (ret_reg << 8) | (bit_position)
*
* For example, SSE3 is determined by the fist bit in the ECX
* register for a CPUID call with EAX=1, so we get:
*
* PSNIP_CPU_FEATURE_X86 | (1 << 16) | (2 << 8) | (0) = 0x01010200
*
* We should have information for inputs of EAX=0-7 w/ ECX=0.
*/
PSNIP_CPU_FEATURE_X86_FPU = 0x01010300,
PSNIP_CPU_FEATURE_X86_VME = 0x01010301,
PSNIP_CPU_FEATURE_X86_DE = 0x01010302,
PSNIP_CPU_FEATURE_X86_PSE = 0x01010303,
PSNIP_CPU_FEATURE_X86_TSC = 0x01010304,
PSNIP_CPU_FEATURE_X86_MSR = 0x01010305,
PSNIP_CPU_FEATURE_X86_PAE = 0x01010306,
PSNIP_CPU_FEATURE_X86_MCE = 0x01010307,
PSNIP_CPU_FEATURE_X86_CX8 = 0x01010308,
PSNIP_CPU_FEATURE_X86_APIC = 0x01010309,
PSNIP_CPU_FEATURE_X86_SEP = 0x0101030b,
PSNIP_CPU_FEATURE_X86_MTRR = 0x0101030c,
PSNIP_CPU_FEATURE_X86_PGE = 0x0101030d,
PSNIP_CPU_FEATURE_X86_MCA = 0x0101030e,
PSNIP_CPU_FEATURE_X86_CMOV = 0x0101030f,
PSNIP_CPU_FEATURE_X86_PAT = 0x01010310,
PSNIP_CPU_FEATURE_X86_PSE_36 = 0x01010311,
PSNIP_CPU_FEATURE_X86_PSN = 0x01010312,
PSNIP_CPU_FEATURE_X86_CLFSH = 0x01010313,
PSNIP_CPU_FEATURE_X86_DS = 0x01010314,
PSNIP_CPU_FEATURE_X86_ACPI = 0x01010316,
PSNIP_CPU_FEATURE_X86_MMX = 0x01010317,
PSNIP_CPU_FEATURE_X86_FXSR = 0x01010318,
PSNIP_CPU_FEATURE_X86_SSE = 0x01010319,
PSNIP_CPU_FEATURE_X86_SSE2 = 0x0101031a,
PSNIP_CPU_FEATURE_X86_SS = 0x0101031b,
PSNIP_CPU_FEATURE_X86_HTT = 0x0101031c,
PSNIP_CPU_FEATURE_X86_TM = 0x0101031d,
PSNIP_CPU_FEATURE_X86_IA64 = 0x0101031e,
PSNIP_CPU_FEATURE_X86_PBE = 0x0101031f,
PSNIP_CPU_FEATURE_X86_SSE3 = 0x01010200,
PSNIP_CPU_FEATURE_X86_PCLMULQDQ = 0x01010201,
PSNIP_CPU_FEATURE_X86_DTES64 = 0x01010202,
PSNIP_CPU_FEATURE_X86_MONITOR = 0x01010203,
PSNIP_CPU_FEATURE_X86_DS_CPL = 0x01010204,
PSNIP_CPU_FEATURE_X86_VMX = 0x01010205,
PSNIP_CPU_FEATURE_X86_SMX = 0x01010206,
PSNIP_CPU_FEATURE_X86_EST = 0x01010207,
PSNIP_CPU_FEATURE_X86_TM2 = 0x01010208,
PSNIP_CPU_FEATURE_X86_SSSE3 = 0x01010209,
PSNIP_CPU_FEATURE_X86_CNXT_ID = 0x0101020a,
PSNIP_CPU_FEATURE_X86_SDBG = 0x0101020b,
PSNIP_CPU_FEATURE_X86_FMA = 0x0101020c,
PSNIP_CPU_FEATURE_X86_CX16 = 0x0101020d,
PSNIP_CPU_FEATURE_X86_XTPR = 0x0101020e,
PSNIP_CPU_FEATURE_X86_PDCM = 0x0101020f,
PSNIP_CPU_FEATURE_X86_PCID = 0x01010211,
PSNIP_CPU_FEATURE_X86_DCA = 0x01010212,
PSNIP_CPU_FEATURE_X86_SSE4_1 = 0x01010213,
PSNIP_CPU_FEATURE_X86_SSE4_2 = 0x01010214,
PSNIP_CPU_FEATURE_X86_X2APIC = 0x01010215,
PSNIP_CPU_FEATURE_X86_MOVBE = 0x01010216,
PSNIP_CPU_FEATURE_X86_POPCNT = 0x01010217,
PSNIP_CPU_FEATURE_X86_TSC_DEADLINE = 0x01010218,
PSNIP_CPU_FEATURE_X86_AES = 0x01010219,
PSNIP_CPU_FEATURE_X86_XSAVE = 0x0101021a,
PSNIP_CPU_FEATURE_X86_OSXSAVE = 0x0101021b,
PSNIP_CPU_FEATURE_X86_AVX = 0x0101021c,
PSNIP_CPU_FEATURE_X86_F16C = 0x0101021d,
PSNIP_CPU_FEATURE_X86_RDRND = 0x0101021e,
PSNIP_CPU_FEATURE_X86_HYPERVISOR = 0x0101021f,
PSNIP_CPU_FEATURE_X86_FSGSBASE = 0x01070100,
PSNIP_CPU_FEATURE_X86_TSC_ADJ = 0x01070101,
PSNIP_CPU_FEATURE_X86_SGX = 0x01070102,
PSNIP_CPU_FEATURE_X86_BMI1 = 0x01070103,
PSNIP_CPU_FEATURE_X86_HLE = 0x01070104,
PSNIP_CPU_FEATURE_X86_AVX2 = 0x01070105,
PSNIP_CPU_FEATURE_X86_SMEP = 0x01070107,
PSNIP_CPU_FEATURE_X86_BMI2 = 0x01070108,
PSNIP_CPU_FEATURE_X86_ERMS = 0x01070109,
PSNIP_CPU_FEATURE_X86_INVPCID = 0x0107010a,
PSNIP_CPU_FEATURE_X86_RTM = 0x0107010b,
PSNIP_CPU_FEATURE_X86_PQM = 0x0107010c,
PSNIP_CPU_FEATURE_X86_MPX = 0x0107010e,
PSNIP_CPU_FEATURE_X86_PQE = 0x0107010f,
PSNIP_CPU_FEATURE_X86_AVX512F = 0x01070110,
PSNIP_CPU_FEATURE_X86_AVX512DQ = 0x01070111,
PSNIP_CPU_FEATURE_X86_RDSEED = 0x01070112,
PSNIP_CPU_FEATURE_X86_ADX = 0x01070113,
PSNIP_CPU_FEATURE_X86_SMAP = 0x01070114,
PSNIP_CPU_FEATURE_X86_AVX512IFMA = 0x01070115,
PSNIP_CPU_FEATURE_X86_PCOMMIT = 0x01070116,
PSNIP_CPU_FEATURE_X86_CLFLUSHOPT = 0x01070117,
PSNIP_CPU_FEATURE_X86_CLWB = 0x01070118,
PSNIP_CPU_FEATURE_X86_INTEL_PT = 0x01070119,
PSNIP_CPU_FEATURE_X86_AVX512PF = 0x0107011a,
PSNIP_CPU_FEATURE_X86_AVX512ER = 0x0107011b,
PSNIP_CPU_FEATURE_X86_AVX512CD = 0x0107011c,
PSNIP_CPU_FEATURE_X86_SHA = 0x0107011d,
PSNIP_CPU_FEATURE_X86_AVX512BW = 0x0107011e,
PSNIP_CPU_FEATURE_X86_AVX512VL = 0x0107011f,
PSNIP_CPU_FEATURE_X86_PREFETCHWT1 = 0x01070200,
PSNIP_CPU_FEATURE_X86_AVX512VBMI = 0x01070201,
PSNIP_CPU_FEATURE_X86_UMIP = 0x01070202,
PSNIP_CPU_FEATURE_X86_PKU = 0x01070203,
PSNIP_CPU_FEATURE_X86_OSPKE = 0x01070204,
PSNIP_CPU_FEATURE_X86_AVX512VPOPCNTDQ = 0x0107020e,
PSNIP_CPU_FEATURE_X86_RDPID = 0x01070215,
PSNIP_CPU_FEATURE_X86_SGX_LC = 0x0107021e,
PSNIP_CPU_FEATURE_X86_AVX512_4VNNIW = 0x01070302,
PSNIP_CPU_FEATURE_X86_AVX512_4FMAPS = 0x01070303,
PSNIP_CPU_FEATURE_ARM_SWP = PSNIP_CPU_FEATURE_ARM | 1,
PSNIP_CPU_FEATURE_ARM_HALF = PSNIP_CPU_FEATURE_ARM | 2,
PSNIP_CPU_FEATURE_ARM_THUMB = PSNIP_CPU_FEATURE_ARM | 3,
PSNIP_CPU_FEATURE_ARM_26BIT = PSNIP_CPU_FEATURE_ARM | 4,
PSNIP_CPU_FEATURE_ARM_FAST_MULT = PSNIP_CPU_FEATURE_ARM | 5,
PSNIP_CPU_FEATURE_ARM_FPA = PSNIP_CPU_FEATURE_ARM | 6,
PSNIP_CPU_FEATURE_ARM_VFP = PSNIP_CPU_FEATURE_ARM | 7,
PSNIP_CPU_FEATURE_ARM_EDSP = PSNIP_CPU_FEATURE_ARM | 8,
PSNIP_CPU_FEATURE_ARM_JAVA = PSNIP_CPU_FEATURE_ARM | 9,
PSNIP_CPU_FEATURE_ARM_IWMMXT = PSNIP_CPU_FEATURE_ARM | 10,
PSNIP_CPU_FEATURE_ARM_CRUNCH = PSNIP_CPU_FEATURE_ARM | 11,
PSNIP_CPU_FEATURE_ARM_THUMBEE = PSNIP_CPU_FEATURE_ARM | 12,
PSNIP_CPU_FEATURE_ARM_NEON = PSNIP_CPU_FEATURE_ARM | 13,
PSNIP_CPU_FEATURE_ARM_VFPV3 = PSNIP_CPU_FEATURE_ARM | 14,
PSNIP_CPU_FEATURE_ARM_VFPV3D16 = PSNIP_CPU_FEATURE_ARM | 15,
PSNIP_CPU_FEATURE_ARM_TLS = PSNIP_CPU_FEATURE_ARM | 16,
PSNIP_CPU_FEATURE_ARM_VFPV4 = PSNIP_CPU_FEATURE_ARM | 17,
PSNIP_CPU_FEATURE_ARM_IDIVA = PSNIP_CPU_FEATURE_ARM | 18,
PSNIP_CPU_FEATURE_ARM_IDIVT = PSNIP_CPU_FEATURE_ARM | 19,
PSNIP_CPU_FEATURE_ARM_VFPD32 = PSNIP_CPU_FEATURE_ARM | 20,
PSNIP_CPU_FEATURE_ARM_LPAE = PSNIP_CPU_FEATURE_ARM | 21,
PSNIP_CPU_FEATURE_ARM_EVTSTRM = PSNIP_CPU_FEATURE_ARM | 22,
PSNIP_CPU_FEATURE_ARM_AES = PSNIP_CPU_FEATURE_ARM | 0x0100 | 1,
PSNIP_CPU_FEATURE_ARM_PMULL = PSNIP_CPU_FEATURE_ARM | 0x0100 | 2,
PSNIP_CPU_FEATURE_ARM_SHA1 = PSNIP_CPU_FEATURE_ARM | 0x0100 | 3,
PSNIP_CPU_FEATURE_ARM_SHA2 = PSNIP_CPU_FEATURE_ARM | 0x0100 | 4,
PSNIP_CPU_FEATURE_ARM_CRC32 = PSNIP_CPU_FEATURE_ARM | 0x0100 | 5
};
int psnip_cpu_count (void);
int psnip_cpu_feature_check (enum PSnipCPUFeature feature);
int psnip_cpu_feature_check_many (enum PSnipCPUFeature* feature);
#if defined(__cplusplus)
}
#endif
#endif /* PSNIP_CPU__H */
================================================
FILE: cpuid.cpp
================================================
/*
* cpuid.cpp
*/
#include "cpuid.hpp"
#include <string.h>
using std::uint8_t;
using std::uint32_t;
std::string cpuid_result::to_string() {
std::string s;
s += "eax = " + std::to_string(eax) + ", ";
s += "ebx = " + std::to_string(ebx) + ", ";
s += "ecx = " + std::to_string(ecx) + ", ";
s += "edx = " + std::to_string(edx);
return s;
}
uint32_t cpuid_highest_leaf_inner() {
return cpuid(0).eax;
}
uint32_t cpuid_highest_leaf() {
static uint32_t cached = cpuid_highest_leaf_inner();
return cached;
}
cpuid_result cpuid(int leaf, int subleaf) {
cpuid_result ret = {};
asm ("cpuid"
:
"=a" (ret.eax),
"=b" (ret.ebx),
"=c" (ret.ecx),
"=d" (ret.edx)
:
"a" (leaf),
"c" (subleaf)
);
return ret;
}
cpuid_result cpuid(int leaf) {
return cpuid(leaf, 0);
}
family_model gfm_inner() {
auto cpuid1 = cpuid(1);
family_model ret;
ret.family = (cpuid1.eax >> 8) & 0xF;
ret.model = (cpuid1.eax >> 4) & 0xF;
ret.stepping = (cpuid1.eax ) & 0xF;
if (ret.family == 15) {
ret.family += (cpuid1.eax >> 20) & 0xFF; // extended family
}
if (ret.family == 15 || ret.family == 6) {
ret.model += ((cpuid1.eax >> 16) & 0xF) << 4; // extended model
}
return ret;
}
family_model get_family_model() {
static family_model cached_family_model = gfm_inner();
return cached_family_model;
}
std::string get_brand_string() {
auto check = cpuid(0x80000000);
if (check.eax < 0x80000004) {
return std::string("unkown (eax =") + std::to_string(check.eax) +")";
}
std::string ret;
for (uint32_t eax : {0x80000002, 0x80000003, 0x80000004}) {
char buf[17];
auto fourchars = cpuid(eax);
memcpy(buf + 0, &fourchars.eax, 4);
memcpy(buf + 4, &fourchars.ebx, 4);
memcpy(buf + 8, &fourchars.ecx, 4);
memcpy(buf + 12, &fourchars.edx, 4);
buf[16] = '\0';
ret += buf;
}
return ret;
}
/* get bits [start:end] inclusive of the given value */
uint32_t get_bits(uint32_t value, int start, int end) {
value >>= start;
uint32_t mask = ((uint64_t)-1) << (end - start + 1);
return value & ~mask;
}
/**
* Get the shift amount for unique physical core IDs
*/
int get_smt_shift()
{
if (cpuid_highest_leaf() < 0xb) {
return -1;
}
uint32_t smtShift = -1u;
for (uint32_t subleaf = 0; ; subleaf++) {
cpuid_result leafb = cpuid(0xb, subleaf);
uint32_t type = get_bits(leafb.ecx, 8 ,15);
if (!get_bits(leafb.ebx,0,15) || type == 0) {
// done
break;
}
if (type == 1) {
// here's the value we are after: make sure we don't have more than one entry for
// this type though!
if (smtShift != -1u) {
fprintf(stderr, "Warning: more than one level of type 1 in the x2APIC hierarchy");
}
smtShift = get_bits(leafb.eax, 0, 4);
}
}
return smtShift;
}
================================================
FILE: cpuid.hpp
================================================
/*
* cpuid.hpp
*/
#ifndef CPUID_HPP_
#define CPUID_HPP_
#include <cinttypes>
#include <string>
struct cpuid_result {
std::uint32_t eax, ebx, ecx, edx;
std::string to_string();
};
struct family_model {
uint8_t family;
uint8_t model;
uint8_t stepping;
std::string to_string() {
std::string s;
s += "family = " + std::to_string(family) + ", ";
s += "model = " + std::to_string(model) + ", ";
s += "stepping = " + std::to_string(stepping);
return s;
}
};
/** the highest supported leaf value */
uint32_t cpuid_highest_leaf();
/* return the CPUID result for querying the given leaf (EAX) and no subleaf (ECX=0) */
cpuid_result cpuid(int leaf);
/* return the CPUID result for querying the given leaf (EAX) and subleaf (ECX) */
cpuid_result cpuid(int leaf, int subleaf);
family_model get_family_model();
std::string get_brand_string();
int get_smt_shift();
/* get bits [start:end] inclusive of the given value */
uint32_t get_bits(uint32_t value, int start, int end);
#endif /* CPUID_HPP_ */
================================================
FILE: exact-int.h
================================================
/* Exact-width integer types
* Portable Snippets - https://gitub.com/nemequ/portable-snippets
* Created by Evan Nemerson <evan@nemerson.com>
*
* To the extent possible under law, the authors have waived all
* copyright and related or neighboring rights to this code. For
* details, see the Creative Commons Zero 1.0 Universal license at
* https://creativecommons.org/publicdomain/zero/1.0/
*
* This header tries to define psnip_(u)int(8|16|32|64)_t to
* appropriate types given your system. For most systems this means
* including <stdint.h> and adding a few preprocessor definitions.
*
* If you prefer, you can define any necessary types yourself.
* Snippets in this repository which rely on these types will not
* attempt to include this header if you have already defined the
* types it uses.
*/
#if !defined(PSNIP_EXACT_INT_H)
# define PSNIP_EXACT_INT_H
# if !defined(PSNIP_EXACT_INT_HAVE_STDINT)
# if defined(_STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define PSNIP_EXACT_INT_HAVE_STDINT
# elif defined(__has_include)
# if __has_include(<stdint.h>)
# define PSNIP_EXACT_INT_HAVE_STDINT
# endif
# elif \
defined(HAVE_STDINT_H) || \
defined(_STDINT_H_INCLUDED) || \
defined(_STDINT_H) || \
defined(_STDINT_H_)
# define PSNIP_EXACT_INT_HAVE_STDINT
# elif \
(defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) || \
(defined(_MSC_VER) && (_MSC_VER >= 1600)) || \
(defined(__SUNPRO_C) && (__SUNPRO_C >= 0x570)) || \
(defined(__WATCOMC__) && (__WATCOMC__ >= 1250))
# define PSNIP_EXACT_INT_HAVE_STDINT
# endif
# endif
# if \
defined(__INT8_TYPE__) && defined(__INT16_TYPE__) && defined(__INT32_TYPE__) && defined(__INT64_TYPE__) && \
defined(__UINT8_TYPE__) && defined(__UINT16_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__)
# define psnip_int8_t __INT8_TYPE__
# define psnip_int16_t __INT16_TYPE__
# define psnip_int32_t __INT32_TYPE__
# define psnip_int64_t __INT64_TYPE__
# define psnip_uint8_t __UINT8_TYPE__
# define psnip_uint16_t __UINT16_TYPE__
# define psnip_uint32_t __UINT32_TYPE__
# define psnip_uint64_t __UINT64_TYPE__
# elif defined(PSNIP_EXACT_INT_HAVE_STDINT)
# include <stdint.h>
# if !defined(psnip_int8_t)
# define psnip_int8_t int8_t
# endif
# if !defined(psnip_uint8_t)
# define psnip_uint8_t uint8_t
# endif
# if !defined(psnip_int16_t)
# define psnip_int16_t int16_t
# endif
# if !defined(psnip_uint16_t)
# define psnip_uint16_t uint16_t
# endif
# if !defined(psnip_int32_t)
# define psnip_int32_t int32_t
# endif
# if !defined(psnip_uint32_t)
# define psnip_uint32_t uint32_t
# endif
# if !defined(psnip_int64_t)
# define psnip_int64_t int64_t
# endif
# if !defined(psnip_uint64_t)
# define psnip_uint64_t uint64_t
# endif
# elif defined(_MSC_VER)
# if !defined(psnip_int8_t)
# define psnip_int8_t __int8
# endif
# if !defined(psnip_uint8_t)
# define psnip_uint8_t unsigned __int8
# endif
# if !defined(psnip_int16_t)
# define psnip_int16_t __int16
# endif
# if !defined(psnip_uint16_t)
# define psnip_uint16_t unsigned __int16
# endif
# if !defined(psnip_int32_t)
# define psnip_int32_t __int32
# endif
# if !defined(psnip_uint32_t)
# define psnip_uint32_t unsigned __int32
# endif
# if !defined(psnip_int64_t)
# define psnip_int64_t __int64
# endif
# if !defined(psnip_uint64_t)
# define psnip_uint64_t unsigned __int64
# endif
# else
# include <limits.h>
# if !defined(psnip_int8_t)
# if defined(CHAR_MIN) && defined(CHAR_MAX) && (CHAR_MIN == (-127-1)) && (CHAR_MAX == 127)
# define psnip_int8_t char
# elif defined(SHRT_MIN) && defined(SHRT_MAX) && (SHRT_MIN == (-127-1)) && (SHRT_MAX == 127)
# define psnip_int8_t short
# elif defined(INT_MIN) && defined(INT_MAX) && (INT_MIN == (-127-1)) && (INT_MAX == 127)
# define psnip_int8_t int
# elif defined(LONG_MIN) && defined(LONG_MAX) && (LONG_MIN == (-127-1)) && (LONG_MAX == 127)
# define psnip_int8_t long
# elif defined(LLONG_MIN) && defined(LLONG_MAX) && (LLONG_MIN == (-127-1)) && (LLONG_MAX == 127)
# define psnip_int8_t long long
# else
# error Unable to locate 8-bit signed integer type.
# endif
# endif
# if !defined(psnip_uint8_t)
# if defined(UCHAR_MAX) && (UCHAR_MAX == 255)
# define psnip_uint8_t unsigned char
# elif defined(USHRT_MAX) && (USHRT_MAX == 255)
# define psnip_uint8_t unsigned short
# elif defined(UINT_MAX) && (UINT_MAX == 255)
# define psnip_uint8_t unsigned int
# elif defined(ULONG_MAX) && (ULONG_MAX == 255)
# define psnip_uint8_t unsigned long
# elif defined(ULLONG_MAX) && (ULLONG_MAX == 255)
# define psnip_uint8_t unsigned long long
# else
# error Unable to locate 8-bit unsigned integer type.
# endif
# endif
# if !defined(psnip_int16_t)
# if defined(CHAR_MIN) && defined(CHAR_MAX) && (CHAR_MIN == (-32767-1)) && (CHAR_MAX == 32767)
# define psnip_int16_t char
# elif defined(SHRT_MIN) && defined(SHRT_MAX) && (SHRT_MIN == (-32767-1)) && (SHRT_MAX == 32767)
# define psnip_int16_t short
# elif defined(INT_MIN) && defined(INT_MAX) && (INT_MIN == (-32767-1)) && (INT_MAX == 32767)
# define psnip_int16_t int
# elif defined(LONG_MIN) && defined(LONG_MAX) && (LONG_MIN == (-32767-1)) && (LONG_MAX == 32767)
# define psnip_int16_t long
# elif defined(LLONG_MIN) && defined(LLONG_MAX) && (LLONG_MIN == (-32767-1)) && (LLONG_MAX == 32767)
# define psnip_int16_t long long
# else
# error Unable to locate 16-bit signed integer type.
# endif
# endif
# if !defined(psnip_uint16_t)
# if defined(UCHAR_MAX) && (UCHAR_MAX == 65535)
# define psnip_uint16_t unsigned char
# elif defined(USHRT_MAX) && (USHRT_MAX == 65535)
# define psnip_uint16_t unsigned short
# elif defined(UINT_MAX) && (UINT_MAX == 65535)
# define psnip_uint16_t unsigned int
# elif defined(ULONG_MAX) && (ULONG_MAX == 65535)
# define psnip_uint16_t unsigned long
# elif defined(ULLONG_MAX) && (ULLONG_MAX == 65535)
# define psnip_uint16_t unsigned long long
# else
# error Unable to locate 16-bit unsigned integer type.
# endif
# endif
# if !defined(psnip_int32_t)
# if defined(CHAR_MIN) && defined(CHAR_MAX) && (CHAR_MIN == (-2147483647-1)) && (CHAR_MAX == 2147483647)
# define psnip_int32_t char
# elif defined(SHRT_MIN) && defined(SHRT_MAX) && (SHRT_MIN == (-2147483647-1)) && (SHRT_MAX == 2147483647)
# define psnip_int32_t short
# elif defined(INT_MIN) && defined(INT_MAX) && (INT_MIN == (-2147483647-1)) && (INT_MAX == 2147483647)
# define psnip_int32_t int
# elif defined(LONG_MIN) && defined(LONG_MAX) && (LONG_MIN == (-2147483647-1)) && (LONG_MAX == 2147483647)
# define psnip_int32_t long
# elif defined(LLONG_MIN) && defined(LLONG_MAX) && (LLONG_MIN == (-2147483647-1)) && (LLONG_MAX == 2147483647)
# define psnip_int32_t long long
# else
# error Unable to locate 32-bit signed integer type.
# endif
# endif
# if !defined(psnip_uint32_t)
# if defined(UCHAR_MAX) && (UCHAR_MAX == 4294967295)
# define psnip_uint32_t unsigned char
# elif defined(USHRT_MAX) && (USHRT_MAX == 4294967295)
# define psnip_uint32_t unsigned short
# elif defined(UINT_MAX) && (UINT_MAX == 4294967295)
# define psnip_uint32_t unsigned int
# elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295)
# define psnip_uint32_t unsigned long
# elif defined(ULLONG_MAX) && (ULLONG_MAX == 4294967295)
# define psnip_uint32_t unsigned long long
# else
# error Unable to locate 32-bit unsigned integer type.
# endif
# endif
# if !defined(psnip_int64_t)
# if defined(CHAR_MIN) && defined(CHAR_MAX) && (CHAR_MIN == (-9223372036854775807LL-1)) && (CHAR_MAX == 9223372036854775807LL)
# define psnip_int64_t char
# elif defined(SHRT_MIN) && defined(SHRT_MAX) && (SHRT_MIN == (-9223372036854775807LL-1)) && (SHRT_MAX == 9223372036854775807LL)
# define psnip_int64_t short
# elif defined(INT_MIN) && defined(INT_MAX) && (INT_MIN == (-9223372036854775807LL-1)) && (INT_MAX == 9223372036854775807LL)
# define psnip_int64_t int
# elif defined(LONG_MIN) && defined(LONG_MAX) && (LONG_MIN == (-9223372036854775807LL-1)) && (LONG_MAX == 9223372036854775807LL)
# define psnip_int64_t long
# elif defined(LLONG_MIN) && defined(LLONG_MAX) && (LLONG_MIN == (-9223372036854775807LL-1)) && (LLONG_MAX == 9223372036854775807LL)
# define psnip_int64_t long long
# else
# error Unable to locate 64-bit signed integer type.
# endif
# endif
# if !defined(psnip_uint64_t)
# if defined(UCHAR_MAX) && (UCHAR_MAX == 18446744073709551615ULL)
# define psnip_uint64_t unsigned char
# elif defined(USHRT_MAX) && (USHRT_MAX == 18446744073709551615ULL)
# define psnip_uint64_t unsigned short
# elif defined(UINT_MAX) && (UINT_MAX == 18446744073709551615ULL)
# define psnip_uint64_t unsigned int
# elif defined(ULONG_MAX) && (ULONG_MAX == 18446744073709551615ULL)
# define psnip_uint64_t unsigned long
# elif defined(ULLONG_MAX) && (ULLONG_MAX == 18446744073709551615ULL)
# define psnip_uint64_t unsigned long long
# else
# error Unable to locate 64-bit unsigned integer type.
# endif
# endif
# endif
#endif
================================================
FILE: msr-access.c
================================================
/*
* msr-access.c
*/
// for pread() and sched_getcpu()
#define _GNU_SOURCE
#include "msr-access.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sched.h>
/** if there are this many CPUs or less, we'll never allocate memory */
#define STATIC_ARRAY_SIZE 32
#ifndef MSR_USE_PTHREADS
// thread-safe by default
#define MSR_USE_PTHREADS 1
#endif
#if MSR_USE_PTHREADS
#include <pthread.h>
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void lock() {
pthread_mutex_lock(&mutex);
}
void unlock() {
pthread_mutex_unlock(&mutex);
}
#else
void lock() {}
void unlock(){}
#endif
/* size of the rfile array */
int rfile_static[STATIC_ARRAY_SIZE] = {};
int rfile_size = STATIC_ARRAY_SIZE;
int *rfile_array = rfile_static;
//int rfile_error;
/** get the read-only file associated with the given cpu */
int get_rfile(int cpu) {
assert(cpu >= 0);
lock();
if (cpu >= rfile_size) {
// expand array
size_t new_size = rfile_size * 2 > cpu ? rfile_size * 2 : cpu;
int *new_array = calloc(new_size, sizeof(int));
memcpy(new_array, rfile_array, rfile_size * sizeof(int));
if (rfile_array != rfile_static) {
free(rfile_array);
}
rfile_array = new_array;
rfile_size = new_size;
}
if (rfile_array[cpu] == 0) {
char filename[64] = {};
int ret = snprintf(filename, 64, "/dev/cpu/%d/msr", cpu);
assert(ret > 0);
rfile_array[cpu] = open(filename, O_RDONLY);
if (rfile_array[cpu] == -1) {
rfile_array[cpu] = -errno;
}
}
int ret = rfile_array[cpu];
unlock();
return ret;
}
int read_msr(int cpu, uint32_t msr_index, uint64_t* value) {
int file = get_rfile(cpu);
assert(file);
if (file < 0) {
// file open failes are stored as negative errno
return file;
}
int read = pread(file, value, 8, msr_index);
return read == -1 ? errno : 0;
}
int read_msr_cur_cpu(uint32_t msr_index, uint64_t* value) {
return read_msr(sched_getcpu(), msr_index, value);
}
// rename this to main to build an exe that can be run as ./a.out CPU MSR
// to read MSR from CPU (like a really simple rdmsr)
int test(int argc, char** argv) {
assert(argc == 3);
int cpu = atoi(argv[1]);
uint32_t msr = atoi(argv[2]);
printf("reading msr %u from cpu %d\n", msr, cpu);
uint64_t value = -1;
int res = read_msr(cpu, msr, &value);
if (res) {
printf("error %d\n", res);
} else {
printf("value %lx\n", value);
}
res = read_msr_cur_cpu(msr, &value);
if (res) {
printf("error %d\n", res);
} else {
printf("value %lx\n", value);
}
return EXIT_SUCCESS;
}
================================================
FILE: msr-access.h
================================================
/*
* msr-access.h
*
* Simple API to access the x86 MSR registers exposed on linux with through the /dev/cpu/N/msr file system.
*
* Unless you've changed the msr permissions, only root can do this. The msr filesystem may not exist until
* 'modprobe msr' is executed to load the msr module.
*/
#ifndef MSR_ACCESS_H_
#define MSR_ACCESS_H_
#include <inttypes.h>
// you could get the MSR index values from the following header, although it isn't exported to user-space
// in kernels after 4.12, but you can grab it from the linux source
// #include <asm/msr-index.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Read the MSR given by msr_index on the given cpu, storing the result into
* result, which must point to at least 8 bytes of storage.
*
* Returns zero on success, non-zero on failure.
*
* Negative values indicate errors
* opening the underlying MSR file: the value returned is the negative of the errno
* returned by the kernel when trying to open the file. These file errors is cached
* so once a negative value has been returned for a given cpu, subsequent calls will
* always return the same value.
*
* Positive values indicate failures during the pread call performed to actually read
* the msr from the open file. The value is the errno returned by the kernel after the
* read. The most common value is 5 (EIO) which indicates that you can't read that MSR
* on this hardware (e.g., if may not exist).
*/
int read_msr(int cpu, uint32_t msr_index, uint64_t* value);
/**
* Reads the given MSR on the current CPU. This is just a shortcut for calling
* read_msr(sched_getcpu(), ...), and the result and error handling is the same as that function.
*
* Of course, unless the thread affinity has been restricted for the current thread,
* the result doesn't help the calling code know the true value on the current CPU since
* a context switch can happen at any time (the same caveat applies to getcpu()).
*/
int read_msr_cur_cpu(uint32_t msr_index, uint64_t* value);
#ifdef __cplusplus
} // extern "C" {
#endif
#endif // #ifdef MSR_ACCESS_H_
================================================
FILE: nasm-2.13.03/LICENSE
================================================
NASM is now licensed under the 2-clause BSD license, also known as the
simplified BSD license.
Copyright 1996-2010 the NASM Authors - 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 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.
================================================
FILE: nasm-2.13.03/NOTE
================================================
This stable version of the nasm binary is here in avx-turbo since many version of nasm included in distributions are
capable of compiling AVX-512 (2.11 is required at a minimum). So we include the binary here along with the LICENSE
(which allows such binary distribution).
================================================
FILE: nasm-utils-helper.c
================================================
/*
* nasm-utils-helper.c
*
* C helper functions for some macros in nasm-utils-inc.asm.
*
* If you use any macros that require functionality defined here, just include this C file in
* your project (linked against the same object that contains the assembly generated with the
* help of nasm-utils-inc.asm).
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <assert.h>
// mapping from reg_id to register name
static const char *reg_names[] = {
"rbp",
"rbx",
"r12",
"r13",
"r14",
"r15"
};
/* called when a function using abi_checked_function detects an illegally clobbered register */
void nasm_util_die_on_reg_clobber(const char *fname, unsigned reg_id) {
reg_id--; // reg i
gitextract_u04fsbhh/ ├── .github/ │ └── workflows/ │ └── build.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── args.hxx ├── asm-methods.asm ├── atomic.h ├── avx-turbo.cpp ├── check-uarch.sh ├── config.mk ├── cpu.c ├── cpu.h ├── cpuid.cpp ├── cpuid.hpp ├── exact-int.h ├── msr-access.c ├── msr-access.h ├── nasm-2.13.03/ │ ├── LICENSE │ ├── NOTE │ └── nasm ├── nasm-utils-helper.c ├── nasm-utils-inc.asm ├── once.h ├── stats.hpp ├── table.hpp ├── test/ │ ├── catch.hpp │ ├── unit-test-main.cpp │ └── unit-test.cpp ├── tsc-support.cpp ├── tsc-support.hpp └── util.hpp
Copy disabled (too large)
Download .txt
Showing preview only (376,685K chars total). Download the full file to get everything.
SYMBOL INDEX (1865 symbols across 17 files)
FILE: args.hxx
type args (line 51) | namespace args
function get (line 60) | auto get(Option &option_) -> decltype(option_.Get())
function Glyphs (line 73) | inline std::string::size_type Glyphs(const std::string &string_)
function Wrap (line 95) | inline std::vector<std::string> Wrap(const std::string &in, const std:...
type Error (line 154) | enum class Error
method Error (line 171) | Error(const std::string &problem) : std::runtime_error(problem) {}
class Error (line 168) | class Error : public std::runtime_error
method Error (line 171) | Error(const std::string &problem) : std::runtime_error(problem) {}
class UsageError (line 177) | class UsageError : public Error
method UsageError (line 180) | UsageError(const std::string &problem) : Error(problem) {}
class ParseError (line 186) | class ParseError : public Error
method ParseError (line 189) | ParseError(const std::string &problem) : Error(problem) {}
class ValidationError (line 195) | class ValidationError : public Error
method ValidationError (line 198) | ValidationError(const std::string &problem) : Error(problem) {}
class RequiredError (line 204) | class RequiredError : public ValidationError
method RequiredError (line 207) | RequiredError(const std::string &problem) : ValidationError(problem) {}
class MapError (line 213) | class MapError : public ParseError
method MapError (line 216) | MapError(const std::string &problem) : ParseError(problem) {}
class ExtraError (line 222) | class ExtraError : public ParseError
method ExtraError (line 225) | ExtraError(const std::string &problem) : ParseError(problem) {}
class Help (line 231) | class Help : public Error
method Help (line 234) | Help(const std::string &flag) : Error(flag) {}
type EitherFlag (line 241) | struct EitherFlag
method EitherFlag (line 246) | EitherFlag(const std::string &flag) : isShort(false), shortFlag(), l...
method EitherFlag (line 247) | EitherFlag(const char *flag) : isShort(false), shortFlag(), longFlag...
method EitherFlag (line 248) | EitherFlag(const char flag) : isShort(true), shortFlag(flag), longFl...
method GetLong (line 252) | static std::unordered_set<std::string> GetLong(std::initializer_list...
method GetShort (line 267) | static std::unordered_set<char> GetShort(std::initializer_list<Eithe...
class Matcher (line 289) | class Matcher
method Matcher (line 301) | Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longF...
method Matcher (line 311) | Matcher(Short &&shortIn, Long &&longIn) :
method Matcher (line 327) | Matcher(std::initializer_list<EitherFlag> in) :
method Matcher (line 330) | Matcher(Matcher &&other) : shortFlags(std::move(other.shortFlags)), ...
method Match (line 337) | bool Match(const char flag) const
method Match (line 344) | bool Match(const std::string &flag) const
method GetFlagStrings (line 351) | std::vector<std::string> GetFlagStrings(const std::string &shortPref...
method GetFlagStrings (line 368) | std::vector<std::string> GetFlagStrings(const std::string &shortPref...
type Options (line 385) | enum class Options
function Options (line 404) | inline Options operator | (Options lhs, Options rhs)
function Options (line 409) | inline Options operator & (Options lhs, Options rhs)
class Base (line 416) | class Base
method Base (line 430) | Base(const std::string &help_, Options options_ = {}) : options(opti...
method Options (line 433) | Options GetOptions() const noexcept
method Matched (line 438) | virtual bool Matched() const noexcept
method Validate (line 443) | virtual void Validate(const std::string &, const std::string &)
method GetDescription (line 452) | virtual std::tuple<std::string, std::string> GetDescription(const st...
method Reset (line 459) | virtual void Reset() noexcept
method Error (line 469) | virtual Error GetError() const
class NamedBase (line 478) | class NamedBase : public Base
method NamedBase (line 485) | NamedBase(const std::string &name_, const std::string &help_, Option...
method GetDescription (line 488) | virtual std::tuple<std::string, std::string> GetDescription(const st...
method Name (line 496) | virtual std::string Name() const
method KickOut (line 502) | void KickOut(bool kickout_) noexcept
method KickOut (line 508) | bool KickOut() const noexcept
type Nargs (line 514) | struct Nargs
method Nargs (line 519) | Nargs(size_t min_, size_t max_) : min(min_), max(max_)
method Nargs (line 529) | Nargs(size_t num_) : min(num_), max(num_)
class FlagBase (line 536) | class FlagBase : public NamedBase
method FlagBase (line 542) | FlagBase(const std::string &name_, const std::string &help_, Matcher...
method FlagBase (line 544) | FlagBase(const std::string &name_, const std::string &help_, Matcher...
method FlagBase (line 548) | virtual FlagBase *Match(const std::string &flag)
method Validate (line 568) | virtual void Validate(const std::string &shortPrefix, const std::str...
method FlagBase (line 582) | virtual FlagBase *Match(const char flag)
method GetDescription (line 602) | virtual std::tuple<std::string, std::string> GetDescription(const st...
class ValueFlagBase (line 635) | class ValueFlagBase : public FlagBase
method ValueFlagBase (line 638) | ValueFlagBase(const std::string &name_, const std::string &help_, Ma...
method ValueFlagBase (line 639) | ValueFlagBase(const std::string &name_, const std::string &help_, Ma...
method GetDescription (line 642) | virtual std::tuple<std::string, std::string> GetDescription(const st...
method Nargs (line 660) | virtual Nargs NumberOfArguments() const noexcept override
class PositionalBase (line 668) | class PositionalBase : public NamedBase
method PositionalBase (line 674) | PositionalBase(const std::string &name_, const std::string &help_, O...
method Ready (line 677) | bool Ready()
method Reset (line 684) | virtual void Reset() noexcept override
method Validate (line 693) | virtual void Validate(const std::string &, const std::string &) over...
class Group (line 710) | class Group : public Base
type Validators (line 719) | struct Validators
method Xor (line 721) | static bool Xor(const Group &group)
method AtLeastOne (line 726) | static bool AtLeastOne(const Group &group)
method AtMostOne (line 731) | static bool AtMostOne(const Group &group)
method All (line 736) | static bool All(const Group &group)
method AllOrNone (line 741) | static bool AllOrNone(const Group &group)
method AllChildGroups (line 746) | static bool AllChildGroups(const Group &group)
method DontCare (line 753) | static bool DontCare(const Group &)
method CareTooMuch (line 758) | static bool CareTooMuch(const Group &)
method None (line 763) | static bool None(const Group &group)
method Group (line 769) | Group(const std::string &help_ = std::string(), const std::function<...
method Group (line 771) | Group(Group &group_, const std::string &help_ = std::string(), const...
method FlagBase (line 783) | FlagBase *Match(const T &flag)
method Validate (line 804) | virtual void Validate(const std::string &shortPrefix, const std::str...
method PositionalBase (line 816) | PositionalBase *GetNextPositional()
method HasFlag (line 838) | bool HasFlag() const
method Add (line 859) | void Add(Base &child)
method MatchedChildren (line 873) | std::vector<Base *>::size_type MatchedChildren() const
method Matched (line 880) | virtual bool Matched() const noexcept override
method Get (line 887) | bool Get() const
method GetChildDescriptions (line 894) | std::vector<std::tuple<std::string, std::string, unsigned int>> GetC...
method GetPosNames (line 929) | std::vector<std::string> GetPosNames() const
method Reset (line 949) | virtual void Reset() noexcept override
method Error (line 962) | virtual Error GetError() const override
class ArgumentParser (line 984) | class ArgumentParser : public Group
method RaiseParseError (line 1005) | bool RaiseParseError(const std::string &message)
type OptionType (line 1016) | enum class OptionType
method OptionType (line 1023) | OptionType ParseOption(const std::string &s)
method ParseArgsValues (line 1048) | bool ParseArgsValues(FlagBase &flag, const std::string &arg, It &it,...
method ParseLong (line 1116) | bool ParseLong(It &it, It end)
method ParseShort (line 1155) | bool ParseShort(It &it, It end)
type HelpParams (line 1198) | struct HelpParams
method ArgumentParser (line 1238) | ArgumentParser(const std::string &description_, const std::string &e...
method Prog (line 1257) | void Prog(const std::string &prog_)
method ProglinePostfix (line 1266) | void ProglinePostfix(const std::string &proglinePostfix_)
method Description (line 1275) | void Description(const std::string &description_)
method Epilog (line 1284) | void Epilog(const std::string &epilog_)
method LongPrefix (line 1293) | void LongPrefix(const std::string &longprefix_)
method ShortPrefix (line 1302) | void ShortPrefix(const std::string &shortprefix_)
method LongSeparator (line 1311) | void LongSeparator(const std::string &longseparator_)
method Terminator (line 1332) | void Terminator(const std::string &terminator_)
method GetArgumentSeparations (line 1339) | void GetArgumentSeparations(
method SetArgumentSeparations (line 1358) | void SetArgumentSeparations(
method Help (line 1372) | void Help(std::ostream &help_) const
method Help (line 1473) | std::string Help() const
method It (line 1487) | It ParseArgs(It begin, It end)
method ParseArgs (line 1557) | auto ParseArgs(const T &args) -> decltype(std::begin(args))
method ParseCLI (line 1568) | bool ParseCLI(const int argc, const char * const * argv)
class Flag (line 1587) | class Flag : public FlagBase
method Flag (line 1590) | Flag(Group &group_, const std::string &name_, const std::string &hel...
method Flag (line 1595) | Flag(Group &group_, const std::string &name_, const std::string &hel...
method Get (line 1603) | bool Get() const
method Nargs (line 1608) | virtual Nargs NumberOfArguments() const noexcept override
method ParseValue (line 1613) | virtual void ParseValue(const std::vector<std::string>&) override
class HelpFlag (line 1622) | class HelpFlag : public Flag
method HelpFlag (line 1625) | HelpFlag(Group &group_, const std::string &name_, const std::string ...
method FlagBase (line 1629) | virtual FlagBase *Match(const std::string &arg) override
method FlagBase (line 1643) | virtual FlagBase *Match(const char arg) override
method Get (line 1659) | bool Get() const noexcept
class CounterFlag (line 1667) | class CounterFlag : public Flag
method CounterFlag (line 1674) | CounterFlag(Group &group_, const std::string &name_, const std::stri...
method FlagBase (line 1678) | virtual FlagBase *Match(const std::string &arg) override
method FlagBase (line 1688) | virtual FlagBase *Match(const char arg) override
method Reset (line 1705) | virtual void Reset() noexcept override
type ValueReader (line 1718) | struct ValueReader
type ValueReader<std::string> (line 1745) | struct ValueReader<std::string>
class ValueFlag (line 1762) | class ValueFlag : public ValueFlagBase
method ValueFlag (line 1772) | ValueFlag(Group &group_, const std::string &name_, const std::string...
method ValueFlag (line 1777) | ValueFlag(Group &group_, const std::string &name_, const std::string...
method ValueFlag (line 1781) | ValueFlag(Group &group_, const std::string &name_, const std::string...
method ParseValue (line 1787) | virtual void ParseValue(const std::vector<std::string> &values_) ove...
method T (line 1803) | T &Get() noexcept
class ImplicitValueFlag (line 1817) | class ImplicitValueFlag : public ValueFlag<T, Reader>
method ImplicitValueFlag (line 1826) | ImplicitValueFlag(Group &group_, const std::string &name_, const std...
method ImplicitValueFlag (line 1831) | ImplicitValueFlag(Group &group_, const std::string &name_, const std...
method ImplicitValueFlag (line 1836) | ImplicitValueFlag(Group &group_, const std::string &name_, const std...
method Nargs (line 1843) | virtual Nargs NumberOfArguments() const noexcept override
method ParseValue (line 1848) | virtual void ParseValue(const std::vector<std::string> &value_) over...
method Reset (line 1859) | virtual void Reset() noexcept override
class NargsValueFlag (line 1876) | class NargsValueFlag : public FlagBase
method NargsValueFlag (line 1900) | NargsValueFlag(Group &group_, const std::string &name_, const std::s...
method Nargs (line 1908) | virtual Nargs NumberOfArguments() const noexcept override
method ParseValue (line 1913) | virtual void ParseValue(const std::vector<std::string> &values_) ove...
method iterator (line 1937) | iterator begin() noexcept
method const_iterator (line 1942) | const_iterator begin() const noexcept
method const_iterator (line 1947) | const_iterator cbegin() const noexcept
method iterator (line 1952) | iterator end() noexcept
method const_iterator (line 1957) | const_iterator end() const noexcept
method const_iterator (line 1962) | const_iterator cend() const noexcept
class ValueFlagList (line 1978) | class ValueFlagList : public ValueFlagBase
method ValueFlagList (line 2000) | ValueFlagList(Group &group_, const std::string &name_, const std::st...
method ParseValue (line 2007) | virtual void ParseValue(const std::vector<std::string> &values_) ove...
method Container (line 2025) | Container &Get() noexcept
method Name (line 2030) | virtual std::string Name() const override
method Reset (line 2035) | virtual void Reset() noexcept override
method iterator (line 2041) | iterator begin() noexcept
method const_iterator (line 2046) | const_iterator begin() const noexcept
method const_iterator (line 2051) | const_iterator cbegin() const noexcept
method iterator (line 2056) | iterator end() noexcept
method const_iterator (line 2061) | const_iterator end() const noexcept
method const_iterator (line 2066) | const_iterator cend() const noexcept
class MapFlag (line 2084) | class MapFlag : public ValueFlagBase
method MapFlag (line 2093) | MapFlag(Group &group_, const std::string &name_, const std::string &...
method MapFlag (line 2098) | MapFlag(Group &group_, const std::string &name_, const std::string &...
method MapFlag (line 2102) | MapFlag(Group &group_, const std::string &name_, const std::string &...
method ParseValue (line 2108) | virtual void ParseValue(const std::vector<std::string> &values_) ove...
method T (line 2139) | T &Get() noexcept
class MapFlagList (line 2159) | class MapFlagList : public ValueFlagBase
method MapFlagList (line 2181) | MapFlagList(Group &group_, const std::string &name_, const std::stri...
method ParseValue (line 2188) | virtual void ParseValue(const std::vector<std::string> &values_) ove...
method Container (line 2219) | Container &Get() noexcept
method Name (line 2224) | virtual std::string Name() const override
method Reset (line 2229) | virtual void Reset() noexcept override
method iterator (line 2235) | iterator begin() noexcept
method const_iterator (line 2240) | const_iterator begin() const noexcept
method const_iterator (line 2245) | const_iterator cbegin() const noexcept
method iterator (line 2250) | iterator end() noexcept
method const_iterator (line 2255) | const_iterator end() const noexcept
method const_iterator (line 2260) | const_iterator cend() const noexcept
class Positional (line 2274) | class Positional : public PositionalBase
method Positional (line 2280) | Positional(Group &group_, const std::string &name_, const std::strin...
method Positional (line 2285) | Positional(Group &group_, const std::string &name_, const std::strin...
method ParseValue (line 2291) | virtual void ParseValue(const std::string &value_) override
method T (line 2307) | T &Get() noexcept
class PositionalList (line 2323) | class PositionalList : public PositionalBase
method PositionalList (line 2344) | PositionalList(Group &group_, const std::string &name_, const std::s...
method ParseValue (line 2351) | virtual void ParseValue(const std::string &value_) override
method Name (line 2366) | virtual std::string Name() const override
method Container (line 2373) | Container &Get() noexcept
method Reset (line 2378) | virtual void Reset() noexcept override
method iterator (line 2384) | iterator begin() noexcept
method const_iterator (line 2389) | const_iterator begin() const noexcept
method const_iterator (line 2394) | const_iterator cbegin() const noexcept
method iterator (line 2399) | iterator end() noexcept
method const_iterator (line 2404) | const_iterator end() const noexcept
method const_iterator (line 2409) | const_iterator cend() const noexcept
class MapPositional (line 2427) | class MapPositional : public PositionalBase
method MapPositional (line 2436) | MapPositional(Group &group_, const std::string &name_, const std::st...
method ParseValue (line 2443) | virtual void ParseValue(const std::string &value_) override
method T (line 2474) | T &Get() noexcept
class MapPositionalList (line 2494) | class MapPositionalList : public PositionalBase
method MapPositionalList (line 2517) | MapPositionalList(Group &group_, const std::string &name_, const std...
method ParseValue (line 2524) | virtual void ParseValue(const std::string &value_) override
method Container (line 2554) | Container &Get() noexcept
method Name (line 2559) | virtual std::string Name() const override
method Reset (line 2564) | virtual void Reset() noexcept override
method iterator (line 2570) | iterator begin() noexcept
method const_iterator (line 2575) | const_iterator begin() const noexcept
method const_iterator (line 2580) | const_iterator cbegin() const noexcept
method iterator (line 2585) | iterator end() noexcept
method const_iterator (line 2590) | const_iterator end() const noexcept
method const_iterator (line 2595) | const_iterator cend() const noexcept
FILE: atomic.h
type atomic_int_fast64_t (line 126) | typedef atomic_int_fast64_t psnip_atomic_int64;
type atomic_int_fast32_t (line 127) | typedef atomic_int_fast32_t psnip_atomic_int32;
type psnip_int64_t (line 149) | typedef _Atomic psnip_int64_t psnip_atomic_int64;
type psnip_int32_t (line 150) | typedef _Atomic psnip_int32_t psnip_atomic_int32;
type psnip_int64_t (line 171) | typedef _Atomic psnip_int64_t psnip_atomic_int64;
type psnip_int32_t (line 172) | typedef _Atomic psnip_int32_t psnip_atomic_int32;
type psnip_int64_t (line 174) | typedef psnip_int64_t psnip_atomic_int64;
type psnip_int32_t (line 175) | typedef psnip_int32_t psnip_atomic_int32;
type psnip_int64_t (line 196) | typedef psnip_int64_t psnip_atomic_int64;
type psnip_int32_t (line 197) | typedef psnip_int32_t psnip_atomic_int32;
function PSNIP_ATOMIC__FUNCTION (line 199) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 206) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 220) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 227) | PSNIP_ATOMIC__FUNCTION
type psnip_atomic_int64 (line 248) | typedef long long volatile psnip_atomic_int64;
type psnip_atomic_int32 (line 249) | typedef long volatile psnip_atomic_int32;
type psnip_int64_t (line 285) | typedef psnip_int64_t psnip_atomic_int64;
type psnip_int32_t (line 286) | typedef psnip_int32_t psnip_atomic_int32;
function PSNIP_ATOMIC__FUNCTION (line 288) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 297) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 304) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 316) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 325) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 333) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 342) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 349) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 361) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 370) | PSNIP_ATOMIC__FUNCTION
function PSNIP_ATOMIC__FUNCTION (line 379) | PSNIP_ATOMIC__FUNCTION
FILE: avx-turbo.cpp
type ISA (line 46) | enum ISA {
type test_func (line 55) | struct test_func {
function zeroupper (line 149) | void zeroupper() {
function pin_to_cpu (line 160) | void pin_to_cpu(int cpu) {
type StdClock (line 197) | struct StdClock {
method now_t (line 201) | static now_t now() {
method to_nanos (line 206) | static uint64_t to_nanos(typename CHRONO_CLOCK::duration d) {
type RdtscClock (line 211) | struct RdtscClock {
method now_t (line 215) | static now_t now() {
method to_nanos (line 223) | static uint64_t to_nanos(now_t diff) {
method tsc_freq (line 228) | static uint64_t tsc_freq() {
type outer_timer (line 240) | struct outer_timer {
type dummy_outer (line 246) | struct dummy_outer : outer_timer {
type aperf_ghz (line 254) | struct aperf_ghz : outer_timer {
method aperf_ghz (line 260) | aperf_ghz() : mperf_value(0), aperf_value(0), tsc_value(0), state(STOP...
method mperf (line 262) | static uint64_t mperf() {
method aperf (line 266) | static uint64_t aperf() {
method read (line 270) | static uint64_t read(uint32_t msr) {
method is_supported (line 280) | static bool is_supported() {
method start (line 286) | virtual void start() override {
method stop (line 296) | virtual void stop() override {
method am_ratio (line 307) | double am_ratio() {
method mt_ratio (line 316) | double mt_ratio() {
type inner_result (line 331) | struct inner_result {
type hot_barrier (line 346) | struct hot_barrier {
method hot_barrier (line 349) | hot_barrier(size_t count) : break_count(count), current{0} {}
method increment (line 352) | void increment() {
method is_broken (line 357) | bool is_broken() {
method wait (line 362) | long wait() {
function inner_result (line 378) | inner_result run_test(cal_f* func, size_t iters, outer_timer& outer, hot...
function ISA (line 422) | ISA get_isas() {
function should_run (line 432) | bool should_run(const test_func& t, ISA isas_supported) {
type test_spec (line 440) | struct test_spec {
method test_spec (line 445) | test_spec(std::string name, std::string description) : name{name}, des...
method count (line 448) | size_t count() const { return thread_funcs.size(); }
method to_string (line 450) | std::string to_string() const {
function test_func (line 462) | const test_func *find_one_test(const std::string& id) {
function make_default_tests (line 475) | std::vector<test_spec> make_default_tests(ISA isas_supported, std::vecto...
function make_from_spec (line 526) | std::vector<test_spec> make_from_spec(ISA, std::vector<int> cpus) {
function filter_tests (line 555) | std::vector<test_spec> filter_tests(ISA isas_supported, std::vector<int>...
type result (line 563) | struct result {
type result_holder (line 575) | struct result_holder {
method result_holder (line 579) | result_holder(const test_spec* spec) : spec(spec) {}
method get_overlap1 (line 582) | double get_overlap1() const {
method get_overlap2 (line 588) | double get_overlap2() const {
method get_overlap3 (line 594) | double get_overlap3() const {
type warmup (line 601) | struct warmup {
method warmup (line 603) | warmup(uint64_t millis) : millis{millis} {}
method warm (line 605) | long warm() {
type test_thread (line 615) | struct test_thread {
method test_thread (line 630) | test_thread(size_t id, hot_barrier& start_barrier, hot_barrier& stop_b...
method test_thread (line 637) | test_thread(const test_thread&) = delete;
method test_thread (line 638) | test_thread(test_thread&&) = delete;
function result_string (line 664) | std::string result_string(const std::vector<result>& results, const char...
function report_results (line 673) | void report_results(const std::vector<result_holder>& results_list, bool...
function list_tests (line 723) | void list_tests() {
function get_cpus (line 732) | std::vector<int> get_cpus() {
function filter_cpus (line 755) | std::vector<int> filter_cpus(std::vector<int> cpus) {
function main (line 786) | int main(int argc, char** argv) {
FILE: cpu.c
function psnip_cpu_getid (line 31) | static void psnip_cpu_getid(int func, int* data) {
function psnip_cpu_getid (line 35) | static void psnip_cpu_getid(int func, int* data) {
function psnip_cpu_init (line 56) | static void psnip_cpu_init(void) {
function psnip_cpu_feature_check (line 68) | int
function psnip_cpu_feature_check_many (line 112) | int
function psnip_cpu_count (line 123) | int
FILE: cpu.h
type PSnipCPUFeature (line 28) | enum PSnipCPUFeature {
type PSnipCPUFeature (line 183) | enum PSnipCPUFeature
type PSnipCPUFeature (line 184) | enum PSnipCPUFeature
FILE: cpuid.cpp
function cpuid_highest_leaf_inner (line 22) | uint32_t cpuid_highest_leaf_inner() {
function cpuid_highest_leaf (line 26) | uint32_t cpuid_highest_leaf() {
function cpuid_result (line 31) | cpuid_result cpuid(int leaf, int subleaf) {
function cpuid_result (line 46) | cpuid_result cpuid(int leaf) {
function family_model (line 50) | family_model gfm_inner() {
function family_model (line 65) | family_model get_family_model() {
function get_brand_string (line 70) | std::string get_brand_string() {
function get_bits (line 90) | uint32_t get_bits(uint32_t value, int start, int end) {
function get_smt_shift (line 99) | int get_smt_shift()
FILE: cpuid.hpp
type cpuid_result (line 11) | struct cpuid_result {
type family_model (line 16) | struct family_model {
method to_string (line 20) | std::string to_string() {
FILE: msr-access.c
function lock (line 33) | void lock() {
function unlock (line 36) | void unlock() {
function lock (line 40) | void lock() {}
function unlock (line 41) | void unlock(){}
function get_rfile (line 53) | int get_rfile(int cpu) {
function read_msr (line 87) | int read_msr(int cpu, uint32_t msr_index, uint64_t* value) {
function read_msr_cur_cpu (line 98) | int read_msr_cur_cpu(uint32_t msr_index, uint64_t* value) {
function test (line 105) | int test(int argc, char** argv) {
FILE: nasm-utils-helper.c
function nasm_util_die_on_reg_clobber (line 28) | void nasm_util_die_on_reg_clobber(const char *fname, unsigned reg_id) {
function nasm_util_assert_failed (line 39) | void nasm_util_assert_failed(const char *left, const char *right, const ...
FILE: once.h
type once_flag (line 69) | typedef once_flag psnip_once;
type pthread_once_t (line 73) | typedef pthread_once_t psnip_once;
type INIT_ONCE (line 77) | typedef INIT_ONCE psnip_once;
function BOOL (line 78) | static BOOL CALLBACK psnip_once__callback_wrap(INIT_ONCE* InitOnce, void...
type psnip_atomic_int32 (line 102) | typedef psnip_atomic_int32 psnip_once;
function psnip_once_call (line 103) | static void psnip_once_call(psnip_once* flag, void (*func)(void)) {
type psnip_once (line 119) | typedef int psnip_once;
function psnip_once_call (line 120) | static void psnip_once_call(psnip_once* flag, void (*func)(void)) {
FILE: stats.hpp
type Stats (line 19) | namespace Stats {
class DescriptiveStats (line 21) | class DescriptiveStats {
method DescriptiveStats (line 25) | DescriptiveStats(double min, double max, double avg, double median, ...
method getAvg (line 28) | double getAvg() const {
method getCount (line 32) | size_t getCount() const {
method getMax (line 36) | double getMax() const {
method getMin (line 40) | double getMin() const {
method getMedian (line 44) | double getMedian() const {
method getString4 (line 52) | std::string getString4(int width, int precision) const {
function median (line 65) | typename std::iterator_traits<iter_type>::value_type median(iter_type ...
function medianf (line 83) | typename std::iterator_traits<iter_type>::value_type medianf(iter_type...
function median (line 95) | typename std::iterator_traits<iter_type>::value_type median(iter_type ...
function DescriptiveStats (line 102) | DescriptiveStats get_stats(iter_type first, iter_type last) {
method DescriptiveStats (line 25) | DescriptiveStats(double min, double max, double avg, double median, ...
method getAvg (line 28) | double getAvg() const {
method getCount (line 32) | size_t getCount() const {
method getMax (line 36) | double getMax() const {
method getMin (line 40) | double getMin() const {
method getMedian (line 44) | double getMedian() const {
method getString4 (line 52) | std::string getString4(int width, int precision) const {
FILE: table.hpp
type table (line 17) | namespace table {
function string_format (line 25) | std::string string_format(const std::string& format, Args ... args) {
class Table (line 32) | class Table
method Table (line 106) | Table() : sep(" ") {}
method ColInfo (line 112) | ColInfo& colInfo(size_t col) {
method ColInfo (line 120) | ColInfo colInfo(size_t col) const {
method Row (line 124) | Row& newRow() {
method str (line 130) | std::string str() const {
method setColColumnSeparator (line 156) | void setColColumnSeparator(std::string s) {
type ColInfo (line 34) | struct ColInfo {
type Justification (line 35) | enum Justification { LEFT, RIGHT }
method ColInfo (line 36) | ColInfo() : justify(LEFT) {}
class Row (line 39) | class Row {
method Row (line 46) | Row(const Table& table) : table_(&table) {}
method getSizes (line 49) | std::vector<size_t> getSizes() const {
method justify (line 59) | std::string justify(const ColInfo& cinfo, const std::string& e, size...
method Row (line 71) | Row& add(const T& elem) {
method Row (line 84) | Row& addf(const char* format, Args ... args) {
method size (line 90) | size_t size() {
class Table (line 95) | class Table {
method Table (line 106) | Table() : sep(" ") {}
method ColInfo (line 112) | ColInfo& colInfo(size_t col) {
method ColInfo (line 120) | ColInfo colInfo(size_t col) const {
method Row (line 124) | Row& newRow() {
method str (line 130) | std::string str() const {
method setColColumnSeparator (line 156) | void setColColumnSeparator(std::string s) {
FILE: test/catch.hpp
type Catch (line 98) | namespace Catch {
type CaseSensitive (line 484) | struct CaseSensitive { enum Choice {
type Choice (line 484) | enum Choice {
class NonCopyable (line 489) | class NonCopyable {
method NonCopyable (line 490) | NonCopyable( NonCopyable const& ) = delete;
method NonCopyable (line 491) | NonCopyable( NonCopyable && ) = delete;
method NonCopyable (line 492) | NonCopyable& operator = ( NonCopyable const& ) = delete;
method NonCopyable (line 493) | NonCopyable& operator = ( NonCopyable && ) = delete;
type SourceLineInfo (line 500) | struct SourceLineInfo {
method SourceLineInfo (line 502) | SourceLineInfo() = delete;
method SourceLineInfo (line 503) | SourceLineInfo( char const* _file, std::size_t _line ) noexcept
method SourceLineInfo (line 508) | SourceLineInfo( SourceLineInfo const& other ) = default;
method SourceLineInfo (line 509) | SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
method SourceLineInfo (line 510) | SourceLineInfo( SourceLineInfo&& ) noexcept = default;
method SourceLineInfo (line 511) | SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
method empty (line 513) | bool empty() const noexcept { return file[0] == '\0'; }
type StreamEndStop (line 532) | struct StreamEndStop {
function T (line 536) | T const& operator + ( T const& value, StreamEndStop ) {
type RegistrarForTagAliases (line 547) | struct RegistrarForTagAliases {
class TestSpec (line 568) | class TestSpec
class Pattern (line 5105) | class Pattern {
class NamePattern (line 5116) | class NamePattern : public Pattern {
class TagPattern (line 5124) | class TagPattern : public Pattern {
class ExcludedPattern (line 5132) | class ExcludedPattern : public Pattern {
type Filter (line 5140) | struct Filter {
type FilterMatch (line 5148) | struct FilterMatch {
type ITestInvoker (line 570) | struct ITestInvoker {
class TestCase (line 575) | class TestCase
type IConfig (line 576) | struct IConfig
type ITestCaseRegistry (line 578) | struct ITestCaseRegistry {
class StringRef (line 604) | class StringRef {
method StringRef (line 616) | constexpr StringRef() noexcept = default;
method StringRef (line 620) | constexpr StringRef( char const* rawChars, size_type size ) noexcept
method StringRef (line 625) | StringRef( std::string const& stdString ) noexcept
method empty (line 646) | constexpr auto empty() const noexcept -> bool {
method size (line 649) | constexpr auto size() const noexcept -> size_type {
method isNullTerminated (line 666) | constexpr auto isNullTerminated() const noexcept -> bool {
method const_iterator (line 671) | constexpr const_iterator begin() const { return m_start; }
method const_iterator (line 672) | constexpr const_iterator end() const { return m_start + m_size; }
type always_false (line 923) | struct always_false : std::false_type {}
type true_given (line 925) | struct true_given : std::true_type {}
type is_callable_tester (line 926) | struct is_callable_tester {
type is_callable (line 934) | struct is_callable
class TestInvokerAsMethod (line 960) | class TestInvokerAsMethod : public ITestInvoker {
method TestInvokerAsMethod (line 963) | TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAs...
method invoke (line 965) | void invoke() const override {
function makeTestInvoker (line 974) | auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInv...
type NameAndTags (line 978) | struct NameAndTags {
type AutoReg (line 984) | struct AutoReg : NonCopyable {
type ResultWas (line 1351) | struct ResultWas { enum OfType {
type OfType (line 1351) | enum OfType {
type ResultDisposition (line 1375) | struct ResultDisposition { enum Flags {
type Flags (line 1375) | enum Flags {
function isFalseTest (line 1386) | inline bool isFalseTest( int flags ) { return ( flags & ResultDisposit...
type AssertionInfo (line 1394) | struct AssertionInfo
class StringRef (line 1429) | class StringRef
method StringRef (line 616) | constexpr StringRef() noexcept = default;
method StringRef (line 620) | constexpr StringRef( char const* rawChars, size_type size ) noexcept
method StringRef (line 625) | StringRef( std::string const& stdString ) noexcept
method empty (line 646) | constexpr auto empty() const noexcept -> bool {
method size (line 649) | constexpr auto size() const noexcept -> size_type {
method isNullTerminated (line 666) | constexpr auto isNullTerminated() const noexcept -> bool {
method const_iterator (line 671) | constexpr const_iterator begin() const { return m_start; }
method const_iterator (line 672) | constexpr const_iterator end() const { return m_start + m_size; }
type IStream (line 1431) | struct IStream {
class ReusableStringStream (line 1438) | class ReusableStringStream : NonCopyable {
method get (line 1452) | auto get() -> std::ostream& { return *m_oss; }
type Detail (line 1463) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type IMutableEnumValuesRegistry (line 1474) | struct IMutableEnumValuesRegistry {
type Detail (line 1550) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type StringMaker (line 1613) | struct StringMaker {
method convert (line 1615) | static
method convert (line 1626) | static
type Detail (line 1637) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type StringMaker<std::string> (line 1663) | struct StringMaker<std::string> {
type StringMaker<std::string_view> (line 1669) | struct StringMaker<std::string_view> {
type StringMaker<char const *> (line 1675) | struct StringMaker<char const *> {
type StringMaker<char *> (line 1679) | struct StringMaker<char *> {
type StringMaker<std::wstring> (line 1685) | struct StringMaker<std::wstring> {
type StringMaker<std::wstring_view> (line 1691) | struct StringMaker<std::wstring_view> {
type StringMaker<wchar_t const *> (line 1697) | struct StringMaker<wchar_t const *> {
type StringMaker<wchar_t *> (line 1701) | struct StringMaker<wchar_t *> {
type StringMaker<char[SZ]> (line 1709) | struct StringMaker<char[SZ]> {
method convert (line 1710) | static std::string convert(char const* str) {
type StringMaker<signed char[SZ]> (line 1715) | struct StringMaker<signed char[SZ]> {
method convert (line 1716) | static std::string convert(signed char const* str) {
type StringMaker<unsigned char[SZ]> (line 1721) | struct StringMaker<unsigned char[SZ]> {
method convert (line 1722) | static std::string convert(unsigned char const* str) {
type StringMaker<std::byte> (line 1729) | struct StringMaker<std::byte> {
type StringMaker<int> (line 1734) | struct StringMaker<int> {
type StringMaker<long> (line 1738) | struct StringMaker<long> {
type StringMaker<long long> (line 1742) | struct StringMaker<long long> {
type StringMaker<unsigned int> (line 1746) | struct StringMaker<unsigned int> {
type StringMaker<unsigned long> (line 1750) | struct StringMaker<unsigned long> {
type StringMaker<unsigned long long> (line 1754) | struct StringMaker<unsigned long long> {
type StringMaker<bool> (line 1759) | struct StringMaker<bool> {
type StringMaker<char> (line 1764) | struct StringMaker<char> {
type StringMaker<signed char> (line 1768) | struct StringMaker<signed char> {
type StringMaker<unsigned char> (line 1772) | struct StringMaker<unsigned char> {
type StringMaker<std::nullptr_t> (line 1777) | struct StringMaker<std::nullptr_t> {
type StringMaker<float> (line 1782) | struct StringMaker<float> {
type StringMaker<double> (line 1788) | struct StringMaker<double> {
type StringMaker<T*> (line 1794) | struct StringMaker<T*> {
method convert (line 1796) | static std::string convert(U* p) {
type StringMaker<R C::*> (line 1806) | struct StringMaker<R C::*> {
method convert (line 1807) | static std::string convert(R C::* p) {
type StringMaker<T^> (line 1818) | struct StringMaker<T^> {
method convert (line 1819) | static std::string convert( T^ ref ) {
type Detail (line 1825) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type StringMaker<NSString*> (line 1842) | struct StringMaker<NSString*> {
method convert (line 1843) | static std::string convert(NSString * nsstring) {
type StringMaker<NSObject*> (line 1850) | struct StringMaker<NSObject*> {
method convert (line 1851) | static std::string convert(NSObject* nsObject) {
type Detail (line 1856) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type StringMaker<std::pair<T1, T2> > (line 1883) | struct StringMaker<std::pair<T1, T2> > {
method convert (line 1884) | static std::string convert(const std::pair<T1, T2>& pair) {
type StringMaker<std::optional<T> > (line 1901) | struct StringMaker<std::optional<T> > {
method convert (line 1902) | static std::string convert(const std::optional<T>& optional) {
type Detail (line 1919) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type StringMaker<std::monostate> (line 1960) | struct StringMaker<std::monostate> {
method convert (line 1961) | static std::string convert(const std::monostate&) {
type detail (line 1989) | namespace detail {
type void_type (line 1991) | struct void_type {
type is_range_impl (line 1996) | struct is_range_impl : std::false_type {
type is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> (line 2000) | struct is_range_impl<T, typename void_type<decltype(begin(std::declv...
type is_range (line 2005) | struct is_range : detail::is_range_impl<T> {
type is_range<T^> (line 2010) | struct is_range<T^> {
function rangeToString (line 2016) | std::string rangeToString( Range const& range ) {
function rangeToString (line 2022) | std::string rangeToString( std::vector<bool, Allocator> const& v ) {
type StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> (line 2038) | struct StringMaker<R, typename std::enable_if<is_range<R>::value && !:...
method convert (line 2039) | static std::string convert( R const& range ) {
type StringMaker<T[SZ]> (line 2045) | struct StringMaker<T[SZ]> {
method convert (line 2046) | static std::string convert(T const(&arr)[SZ]) {
type ratio_string (line 2062) | struct ratio_string {
type ratio_string<std::atto> (line 2074) | struct ratio_string<std::atto> {
type ratio_string<std::femto> (line 2078) | struct ratio_string<std::femto> {
type ratio_string<std::pico> (line 2082) | struct ratio_string<std::pico> {
type ratio_string<std::nano> (line 2086) | struct ratio_string<std::nano> {
type ratio_string<std::micro> (line 2090) | struct ratio_string<std::micro> {
type ratio_string<std::milli> (line 2094) | struct ratio_string<std::milli> {
type StringMaker<std::chrono::duration<Value, Ratio>> (line 2101) | struct StringMaker<std::chrono::duration<Value, Ratio>> {
method convert (line 2102) | static std::string convert(std::chrono::duration<Value, Ratio> const...
type StringMaker<std::chrono::duration<Value, std::ratio<1>>> (line 2109) | struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {
method convert (line 2110) | static std::string convert(std::chrono::duration<Value, std::ratio<1...
type StringMaker<std::chrono::duration<Value, std::ratio<60>>> (line 2117) | struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {
method convert (line 2118) | static std::string convert(std::chrono::duration<Value, std::ratio<6...
type StringMaker<std::chrono::duration<Value, std::ratio<3600>>> (line 2125) | struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {
method convert (line 2126) | static std::string convert(std::chrono::duration<Value, std::ratio<3...
type StringMaker<std::chrono::time_point<Clock, Duration>> (line 2137) | struct StringMaker<std::chrono::time_point<Clock, Duration>> {
method convert (line 2138) | static std::string convert(std::chrono::time_point<Clock, Duration> ...
type StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> (line 2144) | struct StringMaker<std::chrono::time_point<std::chrono::system_clock, ...
method convert (line 2145) | static std::string convert(std::chrono::time_point<std::chrono::syst...
type ITransientExpression (line 2200) | struct ITransientExpression {
method isBinaryExpression (line 2201) | auto isBinaryExpression() const -> bool { return m_isBinaryExpressio...
method getResult (line 2202) | auto getResult() const -> bool { return m_result; }
method ITransientExpression (line 2205) | ITransientExpression( bool isBinaryExpression, bool result )
class BinaryExpr (line 2222) | class BinaryExpr : public ITransientExpression {
method streamReconstructedExpression (line 2227) | void streamReconstructedExpression( std::ostream &os ) const override {
method BinaryExpr (line 2233) | BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )
class UnaryExpr (line 2298) | class UnaryExpr : public ITransientExpression {
method streamReconstructedExpression (line 2301) | void streamReconstructedExpression( std::ostream &os ) const override {
method UnaryExpr (line 2306) | explicit UnaryExpr( LhsT lhs )
function compareEqual (line 2314) | auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return...
function compareEqual (line 2316) | auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == re...
function compareEqual (line 2318) | auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == r...
function compareEqual (line 2320) | auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpr...
function compareEqual (line 2322) | auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterp...
function compareNotEqual (line 2325) | auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return s...
function compareNotEqual (line 2327) | auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs !=...
function compareNotEqual (line 2329) | auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs !...
function compareNotEqual (line 2331) | auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinte...
function compareNotEqual (line 2333) | auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reint...
class ExprLhs (line 2336) | class ExprLhs {
method ExprLhs (line 2339) | explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}
method makeUnaryExpr (line 2400) | auto makeUnaryExpr() const -> UnaryExpr<LhsT> {
function handleExpression (line 2408) | void handleExpression( ExprLhs<T> const& expr ) {
type Decomposer (line 2412) | struct Decomposer {
class AssertionResult (line 2437) | class AssertionResult
method AssertionResult (line 5392) | AssertionResult() = delete;
type AssertionInfo (line 2438) | struct AssertionInfo
type SectionInfo (line 2439) | struct SectionInfo
method SectionInfo (line 2864) | SectionInfo
type SectionEndInfo (line 2440) | struct SectionEndInfo
type MessageInfo (line 2441) | struct MessageInfo
type MessageBuilder (line 2442) | struct MessageBuilder
method MessageBuilder (line 2631) | MessageBuilder& operator << ( T const& value ) {
type Counts (line 2443) | struct Counts
type AssertionReaction (line 2444) | struct AssertionReaction
type SourceLineInfo (line 2445) | struct SourceLineInfo
method SourceLineInfo (line 502) | SourceLineInfo() = delete;
method SourceLineInfo (line 503) | SourceLineInfo( char const* _file, std::size_t _line ) noexcept
method SourceLineInfo (line 508) | SourceLineInfo( SourceLineInfo const& other ) = default;
method SourceLineInfo (line 509) | SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
method SourceLineInfo (line 510) | SourceLineInfo( SourceLineInfo&& ) noexcept = default;
method SourceLineInfo (line 511) | SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
method empty (line 513) | bool empty() const noexcept { return file[0] == '\0'; }
type ITransientExpression (line 2447) | struct ITransientExpression
method isBinaryExpression (line 2201) | auto isBinaryExpression() const -> bool { return m_isBinaryExpressio...
method getResult (line 2202) | auto getResult() const -> bool { return m_result; }
method ITransientExpression (line 2205) | ITransientExpression( bool isBinaryExpression, bool result )
type IGeneratorTracker (line 2448) | struct IGeneratorTracker
type BenchmarkInfo (line 2451) | struct BenchmarkInfo
type BenchmarkStats (line 2453) | struct BenchmarkStats
type IResultCapture (line 2456) | struct IResultCapture {
type TestFailureException (line 2519) | struct TestFailureException{}
type AssertionResultData (line 2520) | struct AssertionResultData
method AssertionResultData (line 5378) | AssertionResultData() = delete;
type IResultCapture (line 2521) | struct IResultCapture
class RunContext (line 2522) | class RunContext
method RunContext (line 8057) | RunContext( RunContext const& ) = delete;
method RunContext (line 8058) | RunContext& operator =( RunContext const& ) = delete;
class LazyExpression (line 2524) | class LazyExpression {
method LazyExpression (line 2534) | LazyExpression& operator = ( LazyExpression const& ) = delete;
type AssertionReaction (line 2541) | struct AssertionReaction {
class AssertionHandler (line 2546) | class AssertionHandler {
method handleExpr (line 2565) | void handleExpr( ExprLhs<T> const& expr ) {
type MessageInfo (line 2597) | struct MessageInfo {
type MessageStream (line 2614) | struct MessageStream {
method MessageStream (line 2617) | MessageStream& operator << ( T const& value ) {
type MessageBuilder (line 2625) | struct MessageBuilder : MessageStream {
method MessageBuilder (line 2631) | MessageBuilder& operator << ( T const& value ) {
class ScopedMessage (line 2639) | class ScopedMessage {
method ScopedMessage (line 2642) | ScopedMessage( ScopedMessage& duplicate ) = delete;
class Capturer (line 2650) | class Capturer {
method captureValues (line 2661) | void captureValues( size_t index, T const& value ) {
method captureValues (line 2666) | void captureValues( size_t index, T const& value, Ts const&... value...
type Counts (line 2827) | struct Counts {
type Totals (line 2840) | struct Totals {
type SectionInfo (line 2858) | struct SectionInfo {
method SectionInfo (line 2864) | SectionInfo
type SectionEndInfo (line 2874) | struct SectionEndInfo {
class Timer (line 2892) | class Timer {
class Section (line 2909) | class Section : NonCopyable {
class TestCase (line 2950) | class TestCase
type ITestCaseRegistry (line 2951) | struct ITestCaseRegistry
type IExceptionTranslatorRegistry (line 2952) | struct IExceptionTranslatorRegistry
type IExceptionTranslator (line 2953) | struct IExceptionTranslator
type IReporterRegistry (line 2954) | struct IReporterRegistry
type IReporterFactory (line 2955) | struct IReporterFactory
type ITagAliasRegistry (line 2956) | struct ITagAliasRegistry
type IMutableEnumValuesRegistry (line 2957) | struct IMutableEnumValuesRegistry
class StartupExceptionRegistry (line 2959) | class StartupExceptionRegistry
type IRegistryHub (line 2963) | struct IRegistryHub {
type IMutableRegistryHub (line 2974) | struct IMutableRegistryHub {
type IExceptionTranslator (line 3005) | struct IExceptionTranslator
type IExceptionTranslator (line 3008) | struct IExceptionTranslator {
type IExceptionTranslatorRegistry (line 3013) | struct IExceptionTranslatorRegistry {
class ExceptionTranslatorRegistrar (line 3019) | class ExceptionTranslatorRegistrar {
class ExceptionTranslator (line 3021) | class ExceptionTranslator : public IExceptionTranslator {
method ExceptionTranslator (line 3024) | ExceptionTranslator( std::string(*translateFunction)( T& ) )
method translate (line 3028) | std::string translate( ExceptionTranslators::const_iterator it, Ex...
method ExceptionTranslatorRegistrar (line 3050) | ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
type Detail (line 3074) | namespace Detail {
type EnumInfo (line 1464) | struct EnumInfo {
function rawMemoryToString (line 1557) | std::string rawMemoryToString( const T& object ) {
class IsStreamInsertable (line 1562) | class IsStreamInsertable {
function convertUnstreamable (line 1578) | typename std::enable_if<
function convertUnstreamable (line 1584) | typename std::enable_if<
function convertUnstreamable (line 1591) | typename std::enable_if<
function stringify (line 1642) | std::string stringify(const T& e) {
function convertUnknownEnumToString (line 1647) | std::string convertUnknownEnumToString( E e ) {
function rangeToString (line 1827) | std::string rangeToString(InputIterator first, Sentinel last) {
function stringify (line 1857) | inline std::string stringify( NSString* nsstring ) {
type TupleElementPrinter (line 1925) | struct TupleElementPrinter {
method print (line 1926) | static void print(const Tuple& tuple, std::ostream& os) {
type TupleElementPrinter<Tuple, N, false> (line 1937) | struct TupleElementPrinter<Tuple, N, false> {
method print (line 1938) | static void print(const Tuple&, std::ostream&) {}
class Approx (line 3076) | class Approx {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7878) | Approx Approx::custom() {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
function Approx (line 7882) | Approx Approx::operator-() const {
method Approx (line 3094) | Approx operator()( T const& value ) {
method Approx (line 3103) | explicit Approx( T const& value ): Approx(static_cast<double>(value))
method Approx (line 3148) | Approx& epsilon( T const& newEpsilon ) {
method Approx (line 3155) | Approx& margin( T const& newMargin ) {
method Approx (line 3162) | Approx& scale( T const& newScale ) {
class EnumValuesRegistry (line 10560) | class EnumValuesRegistry : public IMutableEnumValuesRegistry {
function StringRef (line 10587) | StringRef extractInstanceName(StringRef enumInstance) {
function parseEnums (line 10597) | std::vector<StringRef> parseEnums( StringRef enums ) {
function StringRef (line 10609) | StringRef EnumInfo::lookup( int value ) const {
function makeEnumInfo (line 10617) | std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRe...
function EnumInfo (line 10631) | EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName...
class StreamBufImpl (line 13638) | class StreamBufImpl : public std::streambuf {
method StreamBufImpl (line 13643) | StreamBufImpl() {
method overflow (line 13652) | int overflow( int c ) override {
method sync (line 13664) | int sync() override {
type OutputDebugWriter (line 13675) | struct OutputDebugWriter {
class FileStream (line 13684) | class FileStream : public IStream {
method FileStream (line 13687) | FileStream( StringRef filename ) {
class CoutStream (line 13700) | class CoutStream : public IStream {
method CoutStream (line 13705) | CoutStream() : m_os( Catch::cout().rdbuf() ) {}
class DebugOutStream (line 13714) | class DebugOutStream : public IStream {
method DebugOutStream (line 13718) | DebugOutStream()
type Endianness (line 15018) | struct Endianness {
type Arch (line 15019) | enum Arch { Big, Little }
method Arch (line 15021) | static Arch which() {
function rawMemoryToString (line 15031) | std::string rawMemoryToString( const void *object, std::size_t size ) {
type literals (line 3177) | namespace literals {
type StringMaker<Catch::Detail::Approx> (line 3183) | struct StringMaker<Catch::Detail::Approx> {
type pluralise (line 3214) | struct pluralise {
type Matchers (line 3234) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
type Matchers (line 3394) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
type Matchers (line 3421) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
type Matchers (line 3485) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
type Matchers (line 3532) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
type Matchers (line 3601) | namespace Matchers {
type Impl (line 3235) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 3395) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
type Floating (line 3423) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
type Generic (line 3486) | namespace Generic {
type Detail (line 3488) | namespace Detail {
class PredicateMatcher (line 3493) | class PredicateMatcher : public MatcherBase<T> {
method PredicateMatcher (line 3498) | PredicateMatcher(std::function<bool(T const&)> const& elem, std:...
method match (line 3503) | bool match( T const& item ) const override {
method describe (line 3507) | std::string describe() const override {
function Predicate (line 3519) | Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)>...
type StdString (line 3534) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
type Vector (line 3603) | namespace Vector {
type ContainsElementMatcher (line 3605) | struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
method ContainsElementMatcher (line 3607) | ContainsElementMatcher(T const &comparator) : m_comparator( comp...
method match (line 3609) | bool match(std::vector<T, Alloc> const &v) const override {
method describe (line 3618) | std::string describe() const override {
type ContainsMatcher (line 3626) | struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ContainsMatcher (line 3628) | ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m...
method match (line 3630) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3648) | std::string describe() const override {
type EqualsMatcher (line 3656) | struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method EqualsMatcher (line 3658) | EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_c...
method match (line 3660) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3672) | std::string describe() const override {
type ApproxMatcher (line 3679) | struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
method ApproxMatcher (line 3681) | ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_c...
method match (line 3683) | bool match(std::vector<T, AllocMatch> const &v) const override {
method describe (line 3691) | std::string describe() const override {
method ApproxMatcher (line 3695) | ApproxMatcher& epsilon( T const& newEpsilon ) {
method ApproxMatcher (line 3700) | ApproxMatcher& margin( T const& newMargin ) {
method ApproxMatcher (line 3705) | ApproxMatcher& scale( T const& newScale ) {
type UnorderedEqualsMatcher (line 3715) | struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMa...
method UnorderedEqualsMatcher (line 3716) | UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) ...
method match (line 3717) | bool match(std::vector<T, AllocMatch> const& vec) const override {
method describe (line 3724) | std::string describe() const override {
function Contains (line 3737) | Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vec...
function VectorContains (line 3742) | Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& co...
function Equals (line 3747) | Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<...
function Approx (line 3752) | Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<...
function UnorderedEquals (line 3757) | Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEq...
type Impl (line 11399) | namespace Impl {
type MatchAllOf (line 3237) | struct MatchAllOf
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3238) | struct MatchAnyOf
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3239) | struct MatchNotOf
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
class MatcherUntypedBase (line 3241) | class MatcherUntypedBase {
method MatcherUntypedBase (line 3243) | MatcherUntypedBase() = default;
method MatcherUntypedBase (line 3244) | MatcherUntypedBase ( MatcherUntypedBase const& ) = default;
method MatcherUntypedBase (line 3245) | MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = d...
type MatcherMethod (line 3260) | struct MatcherMethod {
type MatcherMethod<NSString*> (line 3268) | struct MatcherMethod<NSString*> {
type MatcherBase (line 3278) | struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {
type MatchAllOf (line 3286) | struct MatchAllOf : MatcherBase<ArgT> {
method match (line 3287) | bool match( ArgT const& arg ) const override {
method describe (line 3294) | std::string describe() const override {
type MatchAnyOf (line 3319) | struct MatchAnyOf : MatcherBase<ArgT> {
method match (line 3321) | bool match( ArgT const& arg ) const override {
method describe (line 3328) | std::string describe() const override {
type MatchNotOf (line 3354) | struct MatchNotOf : MatcherBase<ArgT> {
method MatchNotOf (line 3356) | MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_und...
method match (line 3358) | bool match( ArgT const& arg ) const override {
method describe (line 3362) | std::string describe() const override {
type Exception (line 11421) | namespace Exception {
class ExceptionMessageMatcher (line 3397) | class ExceptionMessageMatcher : public MatcherBase<std::exception> {
method ExceptionMessageMatcher (line 3401) | ExceptionMessageMatcher(std::string const& message):
function Message (line 11432) | Exception::ExceptionMessageMatcher Message(std::string const& messag...
type Floating (line 11556) | namespace Floating {
type FloatingPointKind (line 3425) | enum class FloatingPointKind : uint8_t
type WithinAbsMatcher (line 3427) | struct WithinAbsMatcher : MatcherBase<double> {
type WithinUlpsMatcher (line 3436) | struct WithinUlpsMatcher : MatcherBase<double> {
type WithinRelMatcher (line 3452) | struct WithinRelMatcher : MatcherBase<double> {
type FloatingPointKind (line 11558) | enum class FloatingPointKind : uint8_t {
function WithinULP (line 11656) | Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlp...
function WithinULP (line 11660) | Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpD...
function WithinAbs (line 11664) | Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
function WithinRel (line 11668) | Floating::WithinRelMatcher WithinRel(double target, double eps) {
function WithinRel (line 11672) | Floating::WithinRelMatcher WithinRel(double target) {
function WithinRel (line 11676) | Floating::WithinRelMatcher WithinRel(float target, float eps) {
function WithinRel (line 11680) | Floating::WithinRelMatcher WithinRel(float target) {
type StdString (line 11704) | namespace StdString {
type CasedString (line 3536) | struct CasedString
type StringMatcherBase (line 3546) | struct StringMatcherBase : MatcherBase<std::string> {
type EqualsMatcher (line 3554) | struct EqualsMatcher : StringMatcherBase {
type ContainsMatcher (line 3558) | struct ContainsMatcher : StringMatcherBase {
type StartsWithMatcher (line 3562) | struct StartsWithMatcher : StringMatcherBase {
type EndsWithMatcher (line 3566) | struct EndsWithMatcher : StringMatcherBase {
type RegexMatcher (line 3571) | struct RegexMatcher : MatcherBase<std::string> {
function Equals (line 11779) | StdString::EqualsMatcher Equals( std::string const& str, CaseSensiti...
function Contains (line 11782) | StdString::ContainsMatcher Contains( std::string const& str, CaseSen...
function EndsWith (line 11785) | StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSen...
function StartsWith (line 11788) | StdString::StartsWithMatcher StartsWith( std::string const& str, Cas...
function Matches (line 11792) | StdString::RegexMatcher Matches(std::string const& regex, CaseSensit...
class MatchExpr (line 3768) | class MatchExpr : public ITransientExpression {
method MatchExpr (line 3773) | MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const...
method streamReconstructedExpression (line 3780) | void streamReconstructedExpression( std::ostream &os ) const override {
function makeMatchExpr (line 3795) | auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRe...
type Generators (line 3842) | namespace Generators {
class GeneratorUntypedBase (line 3843) | class GeneratorUntypedBase {
method GeneratorUntypedBase (line 3845) | GeneratorUntypedBase() = default;
type pf (line 3931) | namespace pf{
function make_unique (line 3933) | std::unique_ptr<T> make_unique( Args&&... args ) {
type IGenerator (line 3939) | struct IGenerator : GeneratorUntypedBase {
class SingleValueGenerator (line 3951) | class SingleValueGenerator final : public IGenerator<T> {
method SingleValueGenerator (line 3954) | SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
method T (line 3956) | T const& get() const override {
method next (line 3959) | bool next() override {
class FixedValuesGenerator (line 3965) | class FixedValuesGenerator final : public IGenerator<T> {
method FixedValuesGenerator (line 3972) | FixedValuesGenerator( std::initializer_list<T> values ) : m_values...
method T (line 3974) | T const& get() const override {
method next (line 3977) | bool next() override {
class GeneratorWrapper (line 3984) | class GeneratorWrapper final {
method GeneratorWrapper (line 3987) | GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
method T (line 3990) | T const& get() const {
method next (line 3993) | bool next() {
function value (line 3999) | GeneratorWrapper<T> value(T&& value) {
function values (line 4003) | GeneratorWrapper<T> values(std::initializer_list<T> values) {
class Generators (line 4008) | class Generators : public IGenerator<T> {
method populate (line 4012) | void populate(GeneratorWrapper<T>&& generator) {
method populate (line 4015) | void populate(T&& val) {
method populate (line 4019) | void populate(U&& val) {
method populate (line 4023) | void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
method Generators (line 4030) | Generators(Gs &&... moreGenerators) {
method T (line 4035) | T const& get() const override {
method next (line 4039) | bool next() override {
function table (line 4052) | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std...
type as (line 4058) | struct as {}
function makeGenerators (line 4061) | auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreG...
function makeGenerators (line 4065) | auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators...
function makeGenerators (line 4069) | auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generator...
function makeGenerators (line 4073) | auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Ge...
function generate (line 4083) | auto generate( StringRef generatorName, SourceLineInfo const& lineIn...
class TakeGenerator (line 4118) | class TakeGenerator : public IGenerator<T> {
method TakeGenerator (line 4123) | TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
method T (line 4129) | T const& get() const override {
method next (line 4132) | bool next() override {
function take (line 4149) | GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& genera...
class FilterGenerator (line 4154) | class FilterGenerator : public IGenerator<T> {
method FilterGenerator (line 4159) | FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
method T (line 4173) | T const& get() const override {
method next (line 4177) | bool next() override {
function filter (line 4188) | GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& g...
class RepeatGenerator (line 4193) | class RepeatGenerator : public IGenerator<T> {
method RepeatGenerator (line 4203) | RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
method T (line 4210) | T const& get() const override {
method next (line 4218) | bool next() override {
function repeat (line 4244) | GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& gen...
class MapGenerator (line 4249) | class MapGenerator : public IGenerator<T> {
method MapGenerator (line 4257) | MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
method T (line 4263) | T const& get() const override {
method next (line 4266) | bool next() override {
function map (line 4276) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
function map (line 4283) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
class ChunkGenerator (line 4290) | class ChunkGenerator final : public IGenerator<std::vector<T>> {
method ChunkGenerator (line 4296) | ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
method next (line 4313) | bool next() override {
function chunk (line 4326) | GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper...
class RandomFloatingGenerator (line 4596) | class RandomFloatingGenerator final : public IGenerator<Float> {
method RandomFloatingGenerator (line 4602) | RandomFloatingGenerator(Float a, Float b):
method Float (line 4608) | Float const& get() const override {
method next (line 4611) | bool next() override {
class RandomIntegerGenerator (line 4618) | class RandomIntegerGenerator final : public IGenerator<Integer> {
method RandomIntegerGenerator (line 4624) | RandomIntegerGenerator(Integer a, Integer b):
method Integer (line 4630) | Integer const& get() const override {
method next (line 4633) | bool next() override {
function random (line 4642) | typename std::enable_if<std::is_integral<T>::value && !std::is_same<...
function random (line 4651) | typename std::enable_if<std::is_floating_point<T>::value,
class RangeGenerator (line 4660) | class RangeGenerator final : public IGenerator<T> {
method RangeGenerator (line 4667) | RangeGenerator(T const& start, T const& end, T const& step):
method RangeGenerator (line 4678) | RangeGenerator(T const& start, T const& end):
method T (line 4682) | T const& get() const override {
method next (line 4686) | bool next() override {
function range (line 4693) | GeneratorWrapper<T> range(T const& start, T const& end, T const& ste...
function range (line 4699) | GeneratorWrapper<T> range(T const& start, T const& end) {
class IteratorGenerator (line 4705) | class IteratorGenerator final : public IGenerator<T> {
method IteratorGenerator (line 4714) | IteratorGenerator(InputIterator first, InputSentinel last):m_elems...
method T (line 4720) | T const& get() const override {
method next (line 4724) | bool next() override {
function from_range (line 4733) | GeneratorWrapper<ResultType> from_range(InputIterator from, InputSen...
function from_range (line 4739) | GeneratorWrapper<ResultType> from_range(Container const& cnt) {
function acquireGeneratorTracker (line 10975) | auto acquireGeneratorTracker( StringRef generatorName, SourceLineInf...
type GeneratorTracker (line 12581) | struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorT...
method GeneratorTracker (line 12584) | GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAnd...
method GeneratorTracker (line 12589) | static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTra...
method isGeneratorTracker (line 12626) | bool isGeneratorTracker() const override { return true; }
method hasGenerator (line 12627) | auto hasGenerator() const -> bool override {
method close (line 12630) | void close() override {
method getGenerator (line 12700) | auto getGenerator() const -> GeneratorBasePtr const& override {
method setGenerator (line 12703) | void setGenerator( GeneratorBasePtr&& generator ) override {
type IGeneratorTracker (line 3857) | struct IGeneratorTracker {
function throw_exception (line 3874) | [[noreturn]]
class GeneratorException (line 3917) | class GeneratorException : public std::exception {
method GeneratorException (line 3921) | GeneratorException(const char* msg):
type Generators (line 3928) | namespace Generators {
class GeneratorUntypedBase (line 3843) | class GeneratorUntypedBase {
method GeneratorUntypedBase (line 3845) | GeneratorUntypedBase() = default;
type pf (line 3931) | namespace pf{
function make_unique (line 3933) | std::unique_ptr<T> make_unique( Args&&... args ) {
type IGenerator (line 3939) | struct IGenerator : GeneratorUntypedBase {
class SingleValueGenerator (line 3951) | class SingleValueGenerator final : public IGenerator<T> {
method SingleValueGenerator (line 3954) | SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
method T (line 3956) | T const& get() const override {
method next (line 3959) | bool next() override {
class FixedValuesGenerator (line 3965) | class FixedValuesGenerator final : public IGenerator<T> {
method FixedValuesGenerator (line 3972) | FixedValuesGenerator( std::initializer_list<T> values ) : m_values...
method T (line 3974) | T const& get() const override {
method next (line 3977) | bool next() override {
class GeneratorWrapper (line 3984) | class GeneratorWrapper final {
method GeneratorWrapper (line 3987) | GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
method T (line 3990) | T const& get() const {
method next (line 3993) | bool next() {
function value (line 3999) | GeneratorWrapper<T> value(T&& value) {
function values (line 4003) | GeneratorWrapper<T> values(std::initializer_list<T> values) {
class Generators (line 4008) | class Generators : public IGenerator<T> {
method populate (line 4012) | void populate(GeneratorWrapper<T>&& generator) {
method populate (line 4015) | void populate(T&& val) {
method populate (line 4019) | void populate(U&& val) {
method populate (line 4023) | void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
method Generators (line 4030) | Generators(Gs &&... moreGenerators) {
method T (line 4035) | T const& get() const override {
method next (line 4039) | bool next() override {
function table (line 4052) | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std...
type as (line 4058) | struct as {}
function makeGenerators (line 4061) | auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreG...
function makeGenerators (line 4065) | auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators...
function makeGenerators (line 4069) | auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generator...
function makeGenerators (line 4073) | auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Ge...
function generate (line 4083) | auto generate( StringRef generatorName, SourceLineInfo const& lineIn...
class TakeGenerator (line 4118) | class TakeGenerator : public IGenerator<T> {
method TakeGenerator (line 4123) | TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
method T (line 4129) | T const& get() const override {
method next (line 4132) | bool next() override {
function take (line 4149) | GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& genera...
class FilterGenerator (line 4154) | class FilterGenerator : public IGenerator<T> {
method FilterGenerator (line 4159) | FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
method T (line 4173) | T const& get() const override {
method next (line 4177) | bool next() override {
function filter (line 4188) | GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& g...
class RepeatGenerator (line 4193) | class RepeatGenerator : public IGenerator<T> {
method RepeatGenerator (line 4203) | RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
method T (line 4210) | T const& get() const override {
method next (line 4218) | bool next() override {
function repeat (line 4244) | GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& gen...
class MapGenerator (line 4249) | class MapGenerator : public IGenerator<T> {
method MapGenerator (line 4257) | MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
method T (line 4263) | T const& get() const override {
method next (line 4266) | bool next() override {
function map (line 4276) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
function map (line 4283) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
class ChunkGenerator (line 4290) | class ChunkGenerator final : public IGenerator<std::vector<T>> {
method ChunkGenerator (line 4296) | ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
method next (line 4313) | bool next() override {
function chunk (line 4326) | GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper...
class RandomFloatingGenerator (line 4596) | class RandomFloatingGenerator final : public IGenerator<Float> {
method RandomFloatingGenerator (line 4602) | RandomFloatingGenerator(Float a, Float b):
method Float (line 4608) | Float const& get() const override {
method next (line 4611) | bool next() override {
class RandomIntegerGenerator (line 4618) | class RandomIntegerGenerator final : public IGenerator<Integer> {
method RandomIntegerGenerator (line 4624) | RandomIntegerGenerator(Integer a, Integer b):
method Integer (line 4630) | Integer const& get() const override {
method next (line 4633) | bool next() override {
function random (line 4642) | typename std::enable_if<std::is_integral<T>::value && !std::is_same<...
function random (line 4651) | typename std::enable_if<std::is_floating_point<T>::value,
class RangeGenerator (line 4660) | class RangeGenerator final : public IGenerator<T> {
method RangeGenerator (line 4667) | RangeGenerator(T const& start, T const& end, T const& step):
method RangeGenerator (line 4678) | RangeGenerator(T const& start, T const& end):
method T (line 4682) | T const& get() const override {
method next (line 4686) | bool next() override {
function range (line 4693) | GeneratorWrapper<T> range(T const& start, T const& end, T const& ste...
function range (line 4699) | GeneratorWrapper<T> range(T const& start, T const& end) {
class IteratorGenerator (line 4705) | class IteratorGenerator final : public IGenerator<T> {
method IteratorGenerator (line 4714) | IteratorGenerator(InputIterator first, InputSentinel last):m_elems...
method T (line 4720) | T const& get() const override {
method next (line 4724) | bool next() override {
function from_range (line 4733) | GeneratorWrapper<ResultType> from_range(InputIterator from, InputSen...
function from_range (line 4739) | GeneratorWrapper<ResultType> from_range(Container const& cnt) {
function acquireGeneratorTracker (line 10975) | auto acquireGeneratorTracker( StringRef generatorName, SourceLineInf...
type GeneratorTracker (line 12581) | struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorT...
method GeneratorTracker (line 12584) | GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAnd...
method GeneratorTracker (line 12589) | static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTra...
method isGeneratorTracker (line 12626) | bool isGeneratorTracker() const override { return true; }
method hasGenerator (line 12627) | auto hasGenerator() const -> bool override {
method close (line 12630) | void close() override {
method getGenerator (line 12700) | auto getGenerator() const -> GeneratorBasePtr const& override {
method setGenerator (line 12703) | void setGenerator( GeneratorBasePtr&& generator ) override {
type Generators (line 4115) | namespace Generators {
class GeneratorUntypedBase (line 3843) | class GeneratorUntypedBase {
method GeneratorUntypedBase (line 3845) | GeneratorUntypedBase() = default;
type pf (line 3931) | namespace pf{
function make_unique (line 3933) | std::unique_ptr<T> make_unique( Args&&... args ) {
type IGenerator (line 3939) | struct IGenerator : GeneratorUntypedBase {
class SingleValueGenerator (line 3951) | class SingleValueGenerator final : public IGenerator<T> {
method SingleValueGenerator (line 3954) | SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
method T (line 3956) | T const& get() const override {
method next (line 3959) | bool next() override {
class FixedValuesGenerator (line 3965) | class FixedValuesGenerator final : public IGenerator<T> {
method FixedValuesGenerator (line 3972) | FixedValuesGenerator( std::initializer_list<T> values ) : m_values...
method T (line 3974) | T const& get() const override {
method next (line 3977) | bool next() override {
class GeneratorWrapper (line 3984) | class GeneratorWrapper final {
method GeneratorWrapper (line 3987) | GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
method T (line 3990) | T const& get() const {
method next (line 3993) | bool next() {
function value (line 3999) | GeneratorWrapper<T> value(T&& value) {
function values (line 4003) | GeneratorWrapper<T> values(std::initializer_list<T> values) {
class Generators (line 4008) | class Generators : public IGenerator<T> {
method populate (line 4012) | void populate(GeneratorWrapper<T>&& generator) {
method populate (line 4015) | void populate(T&& val) {
method populate (line 4019) | void populate(U&& val) {
method populate (line 4023) | void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
method Generators (line 4030) | Generators(Gs &&... moreGenerators) {
method T (line 4035) | T const& get() const override {
method next (line 4039) | bool next() override {
function table (line 4052) | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std...
type as (line 4058) | struct as {}
function makeGenerators (line 4061) | auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreG...
function makeGenerators (line 4065) | auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators...
function makeGenerators (line 4069) | auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generator...
function makeGenerators (line 4073) | auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Ge...
function generate (line 4083) | auto generate( StringRef generatorName, SourceLineInfo const& lineIn...
class TakeGenerator (line 4118) | class TakeGenerator : public IGenerator<T> {
method TakeGenerator (line 4123) | TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
method T (line 4129) | T const& get() const override {
method next (line 4132) | bool next() override {
function take (line 4149) | GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& genera...
class FilterGenerator (line 4154) | class FilterGenerator : public IGenerator<T> {
method FilterGenerator (line 4159) | FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
method T (line 4173) | T const& get() const override {
method next (line 4177) | bool next() override {
function filter (line 4188) | GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& g...
class RepeatGenerator (line 4193) | class RepeatGenerator : public IGenerator<T> {
method RepeatGenerator (line 4203) | RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
method T (line 4210) | T const& get() const override {
method next (line 4218) | bool next() override {
function repeat (line 4244) | GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& gen...
class MapGenerator (line 4249) | class MapGenerator : public IGenerator<T> {
method MapGenerator (line 4257) | MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
method T (line 4263) | T const& get() const override {
method next (line 4266) | bool next() override {
function map (line 4276) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
function map (line 4283) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
class ChunkGenerator (line 4290) | class ChunkGenerator final : public IGenerator<std::vector<T>> {
method ChunkGenerator (line 4296) | ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
method next (line 4313) | bool next() override {
function chunk (line 4326) | GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper...
class RandomFloatingGenerator (line 4596) | class RandomFloatingGenerator final : public IGenerator<Float> {
method RandomFloatingGenerator (line 4602) | RandomFloatingGenerator(Float a, Float b):
method Float (line 4608) | Float const& get() const override {
method next (line 4611) | bool next() override {
class RandomIntegerGenerator (line 4618) | class RandomIntegerGenerator final : public IGenerator<Integer> {
method RandomIntegerGenerator (line 4624) | RandomIntegerGenerator(Integer a, Integer b):
method Integer (line 4630) | Integer const& get() const override {
method next (line 4633) | bool next() override {
function random (line 4642) | typename std::enable_if<std::is_integral<T>::value && !std::is_same<...
function random (line 4651) | typename std::enable_if<std::is_floating_point<T>::value,
class RangeGenerator (line 4660) | class RangeGenerator final : public IGenerator<T> {
method RangeGenerator (line 4667) | RangeGenerator(T const& start, T const& end, T const& step):
method RangeGenerator (line 4678) | RangeGenerator(T const& start, T const& end):
method T (line 4682) | T const& get() const override {
method next (line 4686) | bool next() override {
function range (line 4693) | GeneratorWrapper<T> range(T const& start, T const& end, T const& ste...
function range (line 4699) | GeneratorWrapper<T> range(T const& start, T const& end) {
class IteratorGenerator (line 4705) | class IteratorGenerator final : public IGenerator<T> {
method IteratorGenerator (line 4714) | IteratorGenerator(InputIterator first, InputSentinel last):m_elems...
method T (line 4720) | T const& get() const override {
method next (line 4724) | bool next() override {
function from_range (line 4733) | GeneratorWrapper<ResultType> from_range(InputIterator from, InputSen...
function from_range (line 4739) | GeneratorWrapper<ResultType> from_range(Container const& cnt) {
function acquireGeneratorTracker (line 10975) | auto acquireGeneratorTracker( StringRef generatorName, SourceLineInf...
type GeneratorTracker (line 12581) | struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorT...
method GeneratorTracker (line 12584) | GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAnd...
method GeneratorTracker (line 12589) | static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTra...
method isGeneratorTracker (line 12626) | bool isGeneratorTracker() const override { return true; }
method hasGenerator (line 12627) | auto hasGenerator() const -> bool override {
method close (line 12630) | void close() override {
method getGenerator (line 12700) | auto getGenerator() const -> GeneratorBasePtr const& override {
method setGenerator (line 12703) | void setGenerator( GeneratorBasePtr&& generator ) override {
type IResultCapture (line 4344) | struct IResultCapture
type IRunner (line 4345) | struct IRunner
type IConfig (line 4346) | struct IConfig
type IMutableContext (line 4347) | struct IMutableContext
type IContext (line 4351) | struct IContext
type IMutableContext (line 4360) | struct IMutableContext : IContext
function IMutableContext (line 4374) | inline IMutableContext& getCurrentMutableContext()
function IContext (line 4382) | inline IContext& getCurrentContext()
class SimplePcg32 (line 4389) | class SimplePcg32
method SimplePcg32 (line 4563) | SimplePcg32():SimplePcg32(0xed743cc4U) {}
class Option (line 4402) | class Option {
method Option (line 4404) | Option() : nullableValue( nullptr ) {}
method Option (line 4405) | Option( T const& _value )
method Option (line 4408) | Option( Option const& _other )
method Option (line 4416) | Option& operator= ( Option const& _other ) {
method Option (line 4424) | Option& operator = ( T const& _value ) {
method reset (line 4430) | void reset() {
method T (line 4436) | T& operator*() { return *nullableValue; }
method T (line 4437) | T const& operator*() const { return *nullableValue; }
method T (line 4438) | T* operator->() { return nullableValue; }
method T (line 4439) | const T* operator->() const { return nullableValue; }
method T (line 4441) | T valueOr( T const& defaultValue ) const {
method some (line 4445) | bool some() const { return nullableValue != nullptr; }
method none (line 4446) | bool none() const { return nullableValue == nullptr; }
type Verbosity (line 4469) | enum class Verbosity {
type WarnAbout (line 4475) | struct WarnAbout { enum What {
type What (line 4475) | enum What {
type ShowDurations (line 4481) | struct ShowDurations { enum OrNot {
type OrNot (line 4481) | enum OrNot {
type RunTests (line 4486) | struct RunTests { enum InWhatOrder {
type InWhatOrder (line 4486) | enum InWhatOrder {
type UseColour (line 4491) | struct UseColour { enum YesOrNo {
type YesOrNo (line 4491) | enum YesOrNo {
type WaitForKeypress (line 4496) | struct WaitForKeypress { enum When {
type When (line 4496) | enum When {
class TestSpec (line 4503) | class TestSpec
class Pattern (line 5105) | class Pattern {
class NamePattern (line 5116) | class NamePattern : public Pattern {
class TagPattern (line 5124) | class TagPattern : public Pattern {
class ExcludedPattern (line 5132) | class ExcludedPattern : public Pattern {
type Filter (line 5140) | struct Filter {
type FilterMatch (line 5148) | struct FilterMatch {
type IConfig (line 4505) | struct IConfig : NonCopyable {
class SimplePcg32 (line 4551) | class SimplePcg32 {
method SimplePcg32 (line 4563) | SimplePcg32():SimplePcg32(0xed743cc4U) {}
type Generators (line 4593) | namespace Generators {
class GeneratorUntypedBase (line 3843) | class GeneratorUntypedBase {
method GeneratorUntypedBase (line 3845) | GeneratorUntypedBase() = default;
type pf (line 3931) | namespace pf{
function make_unique (line 3933) | std::unique_ptr<T> make_unique( Args&&... args ) {
type IGenerator (line 3939) | struct IGenerator : GeneratorUntypedBase {
class SingleValueGenerator (line 3951) | class SingleValueGenerator final : public IGenerator<T> {
method SingleValueGenerator (line 3954) | SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
method T (line 3956) | T const& get() const override {
method next (line 3959) | bool next() override {
class FixedValuesGenerator (line 3965) | class FixedValuesGenerator final : public IGenerator<T> {
method FixedValuesGenerator (line 3972) | FixedValuesGenerator( std::initializer_list<T> values ) : m_values...
method T (line 3974) | T const& get() const override {
method next (line 3977) | bool next() override {
class GeneratorWrapper (line 3984) | class GeneratorWrapper final {
method GeneratorWrapper (line 3987) | GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):
method T (line 3990) | T const& get() const {
method next (line 3993) | bool next() {
function value (line 3999) | GeneratorWrapper<T> value(T&& value) {
function values (line 4003) | GeneratorWrapper<T> values(std::initializer_list<T> values) {
class Generators (line 4008) | class Generators : public IGenerator<T> {
method populate (line 4012) | void populate(GeneratorWrapper<T>&& generator) {
method populate (line 4015) | void populate(T&& val) {
method populate (line 4019) | void populate(U&& val) {
method populate (line 4023) | void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
method Generators (line 4030) | Generators(Gs &&... moreGenerators) {
method T (line 4035) | T const& get() const override {
method next (line 4039) | bool next() override {
function table (line 4052) | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std...
type as (line 4058) | struct as {}
function makeGenerators (line 4061) | auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreG...
function makeGenerators (line 4065) | auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators...
function makeGenerators (line 4069) | auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generator...
function makeGenerators (line 4073) | auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Ge...
function generate (line 4083) | auto generate( StringRef generatorName, SourceLineInfo const& lineIn...
class TakeGenerator (line 4118) | class TakeGenerator : public IGenerator<T> {
method TakeGenerator (line 4123) | TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):
method T (line 4129) | T const& get() const override {
method next (line 4132) | bool next() override {
function take (line 4149) | GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& genera...
class FilterGenerator (line 4154) | class FilterGenerator : public IGenerator<T> {
method FilterGenerator (line 4159) | FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):
method T (line 4173) | T const& get() const override {
method next (line 4177) | bool next() override {
function filter (line 4188) | GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& g...
class RepeatGenerator (line 4193) | class RepeatGenerator : public IGenerator<T> {
method RepeatGenerator (line 4203) | RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):
method T (line 4210) | T const& get() const override {
method next (line 4218) | bool next() override {
function repeat (line 4244) | GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& gen...
class MapGenerator (line 4249) | class MapGenerator : public IGenerator<T> {
method MapGenerator (line 4257) | MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :
method T (line 4263) | T const& get() const override {
method next (line 4266) | bool next() override {
function map (line 4276) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
function map (line 4283) | GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& gener...
class ChunkGenerator (line 4290) | class ChunkGenerator final : public IGenerator<std::vector<T>> {
method ChunkGenerator (line 4296) | ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :
method next (line 4313) | bool next() override {
function chunk (line 4326) | GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper...
class RandomFloatingGenerator (line 4596) | class RandomFloatingGenerator final : public IGenerator<Float> {
method RandomFloatingGenerator (line 4602) | RandomFloatingGenerator(Float a, Float b):
method Float (line 4608) | Float const& get() const override {
method next (line 4611) | bool next() override {
class RandomIntegerGenerator (line 4618) | class RandomIntegerGenerator final : public IGenerator<Integer> {
method RandomIntegerGenerator (line 4624) | RandomIntegerGenerator(Integer a, Integer b):
method Integer (line 4630) | Integer const& get() const override {
method next (line 4633) | bool next() override {
function random (line 4642) | typename std::enable_if<std::is_integral<T>::value && !std::is_same<...
function random (line 4651) | typename std::enable_if<std::is_floating_point<T>::value,
class RangeGenerator (line 4660) | class RangeGenerator final : public IGenerator<T> {
method RangeGenerator (line 4667) | RangeGenerator(T const& start, T const& end, T const& step):
method RangeGenerator (line 4678) | RangeGenerator(T const& start, T const& end):
method T (line 4682) | T const& get() const override {
method next (line 4686) | bool next() override {
function range (line 4693) | GeneratorWrapper<T> range(T const& start, T const& end, T const& ste...
function range (line 4699) | GeneratorWrapper<T> range(T const& start, T const& end) {
class IteratorGenerator (line 4705) | class IteratorGenerator final : public IGenerator<T> {
method IteratorGenerator (line 4714) | IteratorGenerator(InputIterator first, InputSentinel last):m_elems...
method T (line 4720) | T const& get() const override {
method next (line 4724) | bool next() override {
function from_range (line 4733) | GeneratorWrapper<ResultType> from_range(InputIterator from, InputSen...
function from_range (line 4739) | GeneratorWrapper<ResultType> from_range(Container const& cnt) {
function acquireGeneratorTracker (line 10975) | auto acquireGeneratorTracker( StringRef generatorName, SourceLineInf...
type GeneratorTracker (line 12581) | struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorT...
method GeneratorTracker (line 12584) | GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAnd...
method GeneratorTracker (line 12589) | static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTra...
method isGeneratorTracker (line 12626) | bool isGeneratorTracker() const override { return true; }
method hasGenerator (line 12627) | auto hasGenerator() const -> bool override {
method close (line 12630) | void close() override {
method getGenerator (line 12700) | auto getGenerator() const -> GeneratorBasePtr const& override {
method setGenerator (line 12703) | void setGenerator( GeneratorBasePtr&& generator ) override {
type ITestInvoker (line 4763) | struct ITestInvoker
type TestCaseInfo (line 4765) | struct TestCaseInfo {
type SpecialProperties (line 4766) | enum SpecialProperties{
class TestCase (line 4800) | class TestCase : public TestCaseInfo {
type IRunner (line 4833) | struct IRunner {
class WildcardPattern (line 5073) | class WildcardPattern {
type WildcardPosition (line 5074) | enum WildcardPosition {
type IConfig (line 5102) | struct IConfig
class TestSpec (line 5104) | class TestSpec {
class Pattern (line 5105) | class Pattern {
class NamePattern (line 5116) | class NamePattern : public Pattern {
class TagPattern (line 5124) | class TagPattern : public Pattern {
class ExcludedPattern (line 5132) | class ExcludedPattern : public Pattern {
type Filter (line 5140) | struct Filter {
type FilterMatch (line 5148) | struct FilterMatch {
type TagAlias (line 5178) | struct TagAlias
type ITagAliasRegistry (line 5180) | struct ITagAliasRegistry {
class TestSpecParser (line 5194) | class TestSpecParser {
type Mode (line 5195) | enum Mode{ None, Name, QuotedName, Tag, EscapedName }
method addCharToPattern (line 5236) | inline void addCharToPattern(char c) {
type IStream (line 5264) | struct IStream
type ConfigData (line 5266) | struct ConfigData {
class Config (line 5310) | class Config : public IConfig {
method Config (line 5313) | Config() = default;
type AssertionResultData (line 5376) | struct AssertionResultData
method AssertionResultData (line 5378) | AssertionResultData() = delete;
class AssertionResult (line 5390) | class AssertionResult {
method AssertionResult (line 5392) | AssertionResult() = delete;
type Benchmark (line 5423) | namespace Benchmark {
type Estimate (line 5425) | struct Estimate {
type OutlierClassification (line 5446) | struct OutlierClassification {
method total (line 5453) | int total() const {
type now (line 6462) | struct now {
function keep_memory (line 6486) | inline void keep_memory(T* p) {
function keep_memory (line 6489) | inline void keep_memory() {
type Detail (line 6493) | namespace Detail {
function optimizer_barrier (line 6494) | inline void optimizer_barrier() { keep_memory(); }
function optimizer_barrier (line 6508) | inline void optimizer_barrier() {
type CompleteType (line 6545) | struct CompleteType { using type = T; }
type CompleteType<void> (line 6547) | struct CompleteType<void> { struct type {}; }
type type (line 6547) | struct type {}
type CompleteInvoker (line 6553) | struct CompleteInvoker {
method Result (line 6555) | static Result invoke(Fun&& fun, Args&&... args) {
type CompleteInvoker<void> (line 6560) | struct CompleteInvoker<void> {
method invoke (line 6562) | static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {
function complete_invoke (line 6570) | CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(F...
type ChronometerConcept (line 6593) | struct ChronometerConcept {
type ChronometerModel (line 6599) | struct ChronometerModel final : public ChronometerConcept {
method start (line 6600) | void start() override { started = Clock::now(); }
method finish (line 6601) | void finish() override { finished = Clock::now(); }
method elapsed (line 6603) | ClockDuration<Clock> elapsed() const { return finished - started; }
type is_related (line 6691) | struct is_related
type BenchmarkFunction (line 6701) | struct BenchmarkFunction {
type callable (line 6703) | struct callable {
type model (line 6709) | struct model : public callable {
method model (line 6710) | model(Fun&& fun) : fun(std::move(fun)) {}
method model (line 6711) | model(Fun const& fun) : fun(fun) {}
method call (line 6715) | void call(Chronometer meter) const override {
method call (line 6718) | void call(Chronometer meter, std::true_type) const {
method call (line 6721) | void call(Chronometer meter, std::false_type) const {
type do_nothing (line 6728) | struct do_nothing { void operator()() const {} }
method BenchmarkFunction (line 6731) | BenchmarkFunction(model<T>* c) : f(c) {}
method BenchmarkFunction (line 6734) | BenchmarkFunction()
method BenchmarkFunction (line 6739) | BenchmarkFunction(Fun&& fun)
method BenchmarkFunction (line 6742) | BenchmarkFunction(BenchmarkFunction&& that)
method BenchmarkFunction (line 6745) | BenchmarkFunction(BenchmarkFunction const& that)
method BenchmarkFunction (line 6748) | BenchmarkFunction& operator=(BenchmarkFunction&& that) {
method BenchmarkFunction (line 6753) | BenchmarkFunction& operator=(BenchmarkFunction const& that) {
type repeater (line 6780) | struct repeater {
function repeat (line 6789) | repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {
function measure (line 6835) | TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
function measure_one (line 6854) | TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::f...
function measure_one (line 6858) | TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters...
type optimized_away_error (line 6868) | struct optimized_away_error : std::exception {
function run_for_at_least (line 6875) | TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_...
function OutlierClassification (line 6960) | OutlierClassification classify_outliers(Iterator first, Iterator l...
function mean (line 6984) | double mean(Iterator first, Iterator last) {
function sample (line 6991) | sample resample(URng& rng, int resamples, Iterator first, Iterator...
function sample (line 7008) | sample jackknife(Estimator&& estimator, Iterator first, Iterator l...
function normal_cdf (line 7022) | inline double normal_cdf(double x) {
function bootstrap (line 7031) | Estimate<double> bootstrap(double confidence_level, Iterator first...
type bootstrap_analysis (line 7072) | struct bootstrap_analysis {
function resolution (line 7094) | std::vector<double> resolution(int k) {
function warmup (line 7119) | int warmup() {
function estimate_clock_resolution (line 7124) | EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolutio...
function estimate_clock_cost (line 7133) | EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(Floa...
function measure_environment (line 7161) | Environment<FloatDuration<Clock>> measure_environment() {
function analyse (line 7230) | SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<D...
type ObjectStorage (line 7389) | struct ObjectStorage
method ObjectStorage (line 7393) | ObjectStorage() : data() {}
method ObjectStorage (line 7395) | ObjectStorage(const ObjectStorage& other)
method ObjectStorage (line 7400) | ObjectStorage(ObjectStorage
Condensed preview — 33 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (922K chars).
[
{
"path": ".github/workflows/build.yml",
"chars": 1283,
"preview": "name: build\non: [push]\njobs:\n build:\n runs-on: ${{ matrix.os }}\n strategy:\n fail-fast: false\n matrix:\n "
},
{
"path": ".gitignore",
"chars": 515,
"preview": "# Prerequisites\n*.d\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic"
},
{
"path": ".travis.yml",
"chars": 1853,
"preview": "dist: xenial\nlanguage: cpp\nsudo: false\nbranches:\n except:\n - /^(wip\\/)?(appveyor|msvc|mingw|windows)(\\-.+)?$/\n\naddon"
},
{
"path": "LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2018 travisdowns\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "Makefile",
"chars": 1300,
"preview": "include config.mk\n\n# rebuild when makefile changes\n-include dummy.rebuild\n\n.PHONY: all clean\n\nASM_FLAGS ?= -DNASM_ENABLE"
},
{
"path": "README.md",
"chars": 11239,
"preview": "# avx-turbo\n\nTest the non-AVX, AVX2 and AVX-512 speeds for various types of CPU intensive loops with varying scalar and "
},
{
"path": "args.hxx",
"chars": 91197,
"preview": "/* Copyright (c) 2016-2017 Taylor C. Richberger <taywee@gmx.com> and Pavel\n * Belikov\n * \n * Permission is hereby grante"
},
{
"path": "asm-methods.asm",
"chars": 7515,
"preview": "BITS 64\ndefault rel\n\n%if (__NASM_MAJOR__ < 2) || (__NASM_MINOR__ < 11)\n%deftok ver __NASM_VER__\n%error Your nasm version"
},
{
"path": "atomic.h",
"chars": 13597,
"preview": "/* Atomic operations (v1)\n * Portable Snippets - https://gitub.com/nemequ/portable-snippets\n * Created by Evan Nemerson "
},
{
"path": "avx-turbo.cpp",
"chars": 31790,
"preview": "/*\n * avx-turbo.cpp\n */\n\n#include \"args.hxx\"\n#include \"cpu.h\"\n#include \"cpuid.hpp\"\n#include \"msr-access.h\"\n#include \"sta"
},
{
"path": "check-uarch.sh",
"chars": 558,
"preview": "#!/bin/bash\nset -e\n\n# runs Intel SDE to check that ./avx-turbo works for every arch\nall_arch=( \\\n p4p \\\n m"
},
{
"path": "config.mk",
"chars": 312,
"preview": "-include local.mk\n\n# set DEBUG to 1 to enable various debugging checks\nDEBUG ?= 0\n\n# The assembler to use. Defaults to n"
},
{
"path": "cpu.c",
"chars": 4483,
"preview": "/* CPU Information (v1)\n * Portable Snippets - https://gitub.com/nemequ/portable-snippets\n * Created by Evan Nemerson <e"
},
{
"path": "cpu.h",
"chars": 9183,
"preview": "/* CPU Information (v1)\n * Portable Snippets - https://gitub.com/nemequ/portable-snippets\n * Created by Evan Nemerson <e"
},
{
"path": "cpuid.cpp",
"chars": 3109,
"preview": "/*\n * cpuid.cpp\n */\n\n#include \"cpuid.hpp\"\n\n#include <string.h>\n\nusing std::uint8_t;\nusing std::uint32_t;\n\n\nstd::string c"
},
{
"path": "cpuid.hpp",
"chars": 1068,
"preview": "/*\n * cpuid.hpp\n */\n\n#ifndef CPUID_HPP_\n#define CPUID_HPP_\n\n#include <cinttypes>\n#include <string>\n\nstruct cpuid_result "
},
{
"path": "exact-int.h",
"chars": 9780,
"preview": "/* Exact-width integer types\n * Portable Snippets - https://gitub.com/nemequ/portable-snippets\n * Created by Evan Nemers"
},
{
"path": "msr-access.c",
"chars": 2901,
"preview": "/*\n * msr-access.c\n */\n\n// for pread() and sched_getcpu()\n#define _GNU_SOURCE\n\n#include \"msr-access.h\"\n\n#include <sys/ty"
},
{
"path": "msr-access.h",
"chars": 2085,
"preview": "/*\n * msr-access.h\n *\n * Simple API to access the x86 MSR registers exposed on linux with through the /dev/cpu/N/msr fil"
},
{
"path": "nasm-2.13.03/LICENSE",
"chars": 1521,
"preview": "NASM is now licensed under the 2-clause BSD license, also known as the\nsimplified BSD license.\n\n Copyright 1996-2010 "
},
{
"path": "nasm-2.13.03/NOTE",
"chars": 274,
"preview": "This stable version of the nasm binary is here in avx-turbo since many version of nasm included in distributions are\ncap"
},
{
"path": "nasm-utils-helper.c",
"chars": 1375,
"preview": "/*\n * nasm-utils-helper.c\n *\n * C helper functions for some macros in nasm-utils-inc.asm.\n *\n * If you use any macros th"
},
{
"path": "nasm-utils-inc.asm",
"chars": 6406,
"preview": ";; potentially useful macros for asm development\n\n;; long-nop instructions: nopX inserts a nop of X bytes\n;; see \"Table "
},
{
"path": "once.h",
"chars": 4272,
"preview": "/* Once (v1)\n * Portable Snippets - https://gitub.com/nemequ/portable-snippets\n * Created by Evan Nemerson <evan@nemerso"
},
{
"path": "stats.hpp",
"chars": 3669,
"preview": "/*\n * Really simple descriptive stats.\n *\n * stats.hpp\n */\n\n#ifndef STATS_HPP_\n#define STATS_HPP_\n\n#include <string>\n#in"
},
{
"path": "table.hpp",
"chars": 4585,
"preview": "/*\n * table.hpp\n *\n * Simple tabular output.\n */\n\n#ifndef TABLE_HPP_\n#define TABLE_HPP_\n\n#include <vector>\n#include <sst"
},
{
"path": "test/catch.hpp",
"chars": 657891,
"preview": "/*\n * Catch v2.13.7\n * Generated: 2021-07-28 20:29:27.753164\n * -----------------------------------------------------"
},
{
"path": "test/unit-test-main.cpp",
"chars": 220,
"preview": "/*\n * The implementation and main() function for the Catch2 unit tests.\n *\n * unit-test-main.cpp\n */\n\n// This tells Catc"
},
{
"path": "test/unit-test.cpp",
"chars": 4074,
"preview": "/*\n * unit-test.cpp\n */\n\n#include <string>\n\n\n#include \"catch.hpp\"\n\n#include \"../util.hpp\"\n#include \"../cpuid.hpp\"\n\n#incl"
},
{
"path": "tsc-support.cpp",
"chars": 3319,
"preview": "/*\n * tsc-support.cpp\n */\n\n#include \"tsc-support.hpp\"\n#include \"cpuid.hpp\"\n\n#include <cinttypes>\n#include <string>\n#incl"
},
{
"path": "tsc-support.hpp",
"chars": 684,
"preview": "/*\n * tsc-support.cpp\n */\n\n#include <cinttypes>\n#include <string>\n\n#ifdef _MSC_VER\n#include <intrin.h>\n#else\n#include <x"
},
{
"path": "util.hpp",
"chars": 8051,
"preview": "/*\n * util.hpp\n */\n\n#ifndef UTIL_HPP_\n#define UTIL_HPP_\n\n#include <utility>\n#include <iterator>\n#include <algorithm>\n#in"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the travisdowns/avx-turbo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 33 files (870.3 KB), approximately 208.9k tokens, and a symbol index with 1865 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.