Full Code of GabrielDosReis/ipr for AI

main 3ada312a950f cached
50 files
1.1 MB
282.2k tokens
573 symbols
1 requests
Download .txt
Showing preview only (1,161K chars total). Download the full file or copy to clipboard to get everything.
Repository: GabrielDosReis/ipr
Branch: main
Commit: 3ada312a950f
Files: 50
Total size: 1.1 MB

Directory structure:
gitextract_hqqsamgp/

├── .github/
│   └── workflows/
│       ├── analysis.yml
│       ├── docs.yaml
│       └── main.yml
├── .gitignore
├── 3rdparty/
│   └── doctest/
│       └── doctest.h
├── CMakeLists.txt
├── ChangeLog
├── INSTALL
├── LICENSE
├── README.md
├── STYLE.md
├── cmake/
│   └── UseLATEX.cmake
├── doc/
│   ├── CMakeLists.txt
│   ├── ChangeLog
│   ├── ipr.bib
│   ├── macro.tex
│   ├── ref.tex
│   └── user-guide.tex
├── include/
│   ├── ChangeLog
│   └── ipr/
│       ├── impl
│       ├── input
│       ├── lexer
│       ├── node-category
│       ├── std-preamble
│       └── utility-impl
├── infra/
│   └── Analysis.ruleset
├── src/
│   ├── ChangeLog
│   ├── builtin.def
│   ├── cxx-ipr-io.cxx
│   ├── cxx-ipr-io.ixx
│   ├── cxx-ipr-syntax.ixx
│   ├── cxx-ipr-traversal.cxx
│   ├── cxx-ipr-traversal.ixx
│   ├── cxx-ipr-vocabulary.ixx
│   ├── cxx-ipr.cxx
│   ├── cxx-ipr.ixx
│   ├── impl.cxx
│   ├── input.cxx
│   └── utility.cxx
└── tests/
    ├── CMakeLists.txt
    └── unit-tests/
        ├── CMakeLists.txt
        ├── conversions.cxx
        ├── lines.cxx
        ├── main.cxx
        ├── phased-eval.cxx
        ├── region-owner.cxx
        ├── simple.cxx
        ├── specifiers.cxx
        ├── warehouse.cxx
        └── words.cxx

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/analysis.yml
================================================
name: Analysis

on:
  push:
    paths-ignore:
      - 'doc/**'
    branches: [ main ]
  pull_request:
    paths-ignore:
      - 'doc/**'
    branches: [ main ]

jobs:
  build:
    name: Microsoft C++ Code Analysis
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        config: [Release]

    steps:
      - uses: actions/checkout@v4

      - name: Install MSVC Build Tools Preview
        shell: pwsh
        run: |
          $url = "https://aka.ms/vs/18/insiders/vs_buildtools.exe"
          Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\vs_buildtools.exe" -UseBasicParsing
          $process = Start-Process -Wait -PassThru -FilePath "$env:TEMP\vs_buildtools.exe" `
            -ArgumentList "--quiet  --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --add Microsoft.VisualStudio.Component.VC.CMake.Project --includeRecommended"
          $exitCode = $process.ExitCode
          Write-Output "VS installer exit code: $exitCode"
          if ($exitCode -notin 0,3010,3015) { throw "VS Installer failed: $exitCode" }

      - name: Set up MSVC environment
        uses: ilammy/msvc-dev-cmd@v1
        with:
          vsversion: '18'

      - name: Configure
        shell: pwsh
        run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.config }}

      - name: Build
        shell: pwsh
        run: cmake --build build

      - name: Run Microsoft Visual C++ Analysis
        id: run-analysis
        uses: gdr-at-ms/msvc-code-analysis-action@support-cxx-modules
        with:
          cmakeBuildDirectory: build
          buildConfiguration: ${{ matrix.config }}
          ignoredTargetPaths: ${{ github.workspace }}/tests
          ruleset: '${{ github.workspace }}/infra/Analysis.ruleset'

      - name: Upload SARIF as an Artifact
        uses: actions/upload-artifact@v4
        with:
          name: sarif-file
          path: ${{ steps.run-analysis.outputs.sarif }}
          if-no-files-found: error

      - name: Upload SARIF to GitHub
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: ${{ steps.run-analysis.outputs.sarif }}


================================================
FILE: .github/workflows/docs.yaml
================================================
name: Docs

on:
  push:
    paths:
      - 'doc/**'
      - '.github/workflows/docs.yaml'
    branches: [ main ]
  pull_request:
    paths:
      - 'doc/**'
      - '.github/workflows/docs.yaml'
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    name: Build Ubuntu

    steps:
    - uses: actions/checkout@v2

    - name: Install GCC, CMake
      run: |
        # https://github.com/actions/runner-images/issues/7192
        echo 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
        sudo apt-get update && sudo apt-get -y upgrade --fix-missing
        sudo apt-get install build-essential cmake texlive texlive-latex-extra

    - name: Configure & Build CMake
      uses: lukka/run-cmake@v3
      with:
        buildDirectory: build
        cmakeAppendedArgs: -DBUILD_DOC=ON
        cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
        buildWithCMakeArgs: --target doc


================================================
FILE: .github/workflows/main.yml
================================================
name: Build & Test

on:
  push:
    paths-ignore:
      - 'doc/**'
    branches: [ main ]
  pull_request:
    paths-ignore:
      - 'doc/**'
    branches: [ main ]

jobs:
  # For linux runners
  build-on-linux:
    name: Linux -x- ${{ matrix.name }} -x- ${{ matrix.config }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        config: [Debug, Release]
        name: [gcc-15, clang-21-libstdc++, clang-21-libc++]
        include:
          - name: gcc-15
            compiler: g++-15
            install: |
              sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
              sudo apt-get update
              sudo apt-get install -y g++-15
            cmake_extra: ""
          - name: clang-21-libstdc++
            compiler: clang++-21
            install: |
              wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
              sudo add-apt-repository -y "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-21 main"
              sudo apt-get update
              sudo apt-get install -y clang-21
            cmake_extra: ""
          - name: clang-21-libc++
            compiler: clang++-21
            install: |
              wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
              sudo add-apt-repository -y "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-21 main"
              sudo apt-get update
              sudo apt-get install -y clang-21 libc++-21-dev libc++abi-21-dev
            cmake_extra: "-DCMAKE_CXX_FLAGS=-stdlib=libc++"

    steps:
      - uses: actions/checkout@v4

      - name: Install C++ compilers and tools
        run: |
          # https://github.com/actions/runner-images/issues/7192
          echo 'APT::Get::Always-Include-Phased-Updates "false";' | sudo tee /etc/apt/apt.conf.d/99-phased-updates
          sudo apt-get update && sudo apt-get -y upgrade --fix-missing
          sudo apt-get install -y build-essential cmake ninja-build
          ${{ matrix.install }}

      - name: Configure
        run: >
          cmake -S . -B build -G Ninja
          -DCMAKE_CXX_COMPILER=${{ matrix.compiler }}
          -DCMAKE_BUILD_TYPE=${{ matrix.config }}
          ${{ matrix.cmake_extra }}

      - name: Build
        run: cmake --build build --parallel --config ${{ matrix.config }}

      - name: Test
        run: ctest --test-dir build --output-on-failure

  # For macOS runners
  build-on-macos:
    name: macOS -x- Clang (Homebrew) -x- ${{ matrix.config }}
    runs-on: macos-latest
    strategy:
      fail-fast: false
      matrix:
        config: [Debug, Release]

    steps:
      - uses: actions/checkout@v4

      - name: Install LLVM and CMake
        run: |
          brew install llvm cmake ninja
          echo "$(brew --prefix llvm)/bin" >> $GITHUB_PATH

      - name: Configure
        run: >
          cmake -S . -B build -G Ninja
          -DCMAKE_CXX_COMPILER=$(brew --prefix llvm)/bin/clang++
          -DCMAKE_OSX_SYSROOT=$(xcrun --show-sdk-path)
          -DCMAKE_BUILD_TYPE=${{ matrix.config }}

      - name: Build
        run: cmake --build build --parallel --config ${{ matrix.config }}

      - name: Test
        run: ctest --test-dir build --output-on-failure

  # For Windows runners
  build-on-windows:
    name: Windows -x- MSVC Preview -x- ${{ matrix.config }}
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        config: [Debug, Release]
            
    steps:
      - uses: actions/checkout@v4

      - name: Install MSVC Build Tools Preview
        shell: pwsh
        run: |
          $url = "https://aka.ms/vs/18/insiders/vs_buildtools.exe"
          Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\vs_buildtools.exe" -UseBasicParsing
          $process = Start-Process -Wait -PassThru -FilePath "$env:TEMP\vs_buildtools.exe" `
            -ArgumentList "--quiet  --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --add Microsoft.VisualStudio.Component.VC.CMake.Project --includeRecommended"
          $exitCode = $process.ExitCode
          Write-Output "VS installer exit code: $exitCode"
          if ($exitCode -notin 0,3010,3015) { throw "VS Installer failed: $exitCode" }

      - name: Set up MSVC environment
        uses: ilammy/msvc-dev-cmd@v1
        with:
          vsversion: '18'

      - name: Configure
        shell: pwsh
        run: >
          cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.config }}

      - name: Build
        shell: pwsh
        run: cmake --build build --parallel --config ${{ matrix.config }}

      - name: Test
        shell: pwsh
        run: ctest --test-dir build --output-on-failure


================================================
FILE: .gitignore
================================================
.vscode/
.vs/
build/


================================================
FILE: 3rdparty/doctest/doctest.h
================================================
// ====================================================================== lgtm [cpp/missing-header-guard]
// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! ==
// ======================================================================
//
// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
//
// Copyright (c) 2016-2021 Viktor Kirilov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
// https://opensource.org/licenses/MIT
//
// The documentation can be found at the library's page:
// https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md
//
// =================================================================================================
// =================================================================================================
// =================================================================================================
//
// The library is heavily influenced by Catch - https://github.com/catchorg/Catch2
// which uses the Boost Software License - Version 1.0
// see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt
//
// The concept of subcases (sections in Catch) and expression decomposition are from there.
// Some parts of the code are taken directly:
// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<>
// - the Approx() helper class for floating point comparison
// - colors in the console
// - breaking into a debugger
// - signal / SEH handling
// - timer
// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste)
//
// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest
// which uses the Boost Software License - Version 1.0
// see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt
//
// =================================================================================================
// =================================================================================================
// =================================================================================================

#ifndef DOCTEST_LIBRARY_INCLUDED
#define DOCTEST_LIBRARY_INCLUDED

// =================================================================================================
// == VERSION ======================================================================================
// =================================================================================================

#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH 8

// util we need here
#define DOCTEST_TOSTR_IMPL(x) #x
#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x)

#define DOCTEST_VERSION_STR                                                                        \
    DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "."                                                       \
    DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "."                                                       \
    DOCTEST_TOSTR(DOCTEST_VERSION_PATCH)

#define DOCTEST_VERSION                                                                            \
    (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)

// =================================================================================================
// == COMPILER VERSION =============================================================================
// =================================================================================================

// ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect

#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH))

// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl...
#if defined(_MSC_VER) && defined(_MSC_FULL_VER)
#if _MSC_VER == _MSC_FULL_VER / 10000
#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000)
#else // MSVC
#define DOCTEST_MSVC                                                                               \
    DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000)
#endif // MSVC
#endif // MSVC
#if defined(__clang__) && defined(__clang_minor__)
#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__)
#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) &&              \
        !defined(__INTEL_COMPILER)
#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#endif // GCC

#ifndef DOCTEST_MSVC
#define DOCTEST_MSVC 0
#endif // DOCTEST_MSVC
#ifndef DOCTEST_CLANG
#define DOCTEST_CLANG 0
#endif // DOCTEST_CLANG
#ifndef DOCTEST_GCC
#define DOCTEST_GCC 0
#endif // DOCTEST_GCC

// =================================================================================================
// == COMPILER WARNINGS HELPERS ====================================================================
// =================================================================================================

#if DOCTEST_CLANG
#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push")
#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w)
#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop")
#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)                                                \
    DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w)
#else // DOCTEST_CLANG
#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
#define DOCTEST_CLANG_SUPPRESS_WARNING(w)
#define DOCTEST_CLANG_SUPPRESS_WARNING_POP
#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w)
#endif // DOCTEST_CLANG

#if DOCTEST_GCC
#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x)
#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push")
#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w)
#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop")
#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)                                                  \
    DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w)
#else // DOCTEST_GCC
#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH
#define DOCTEST_GCC_SUPPRESS_WARNING(w)
#define DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w)
#endif // DOCTEST_GCC

#if DOCTEST_MSVC
#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push))
#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w))
#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop))
#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)                                                 \
    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w)
#else // DOCTEST_MSVC
#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
#define DOCTEST_MSVC_SUPPRESS_WARNING(w)
#define DOCTEST_MSVC_SUPPRESS_WARNING_POP
#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w)
#endif // DOCTEST_MSVC

// =================================================================================================
// == COMPILER WARNINGS ============================================================================
// =================================================================================================

// both the header and the implementation suppress all of these,
// so it only makes sense to aggregrate them like so
#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH                                                      \
    DOCTEST_CLANG_SUPPRESS_WARNING_PUSH                                                            \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas")                                            \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables")                                               \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded")                                                     \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes")                                         \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-local-typedef")                                       \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat")                                               \
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")                                      \
                                                                                                   \
    DOCTEST_GCC_SUPPRESS_WARNING_PUSH                                                              \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas")                                              \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas")                                                      \
    DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++")                                                       \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow")                                              \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing")                                              \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations")                                         \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-local-typedefs")                                        \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast")                                                 \
    DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept")                                                     \
                                                                                                   \
    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH                                                             \
    /* these 4 also disabled globally via cmake: */                                                \
    DOCTEST_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */        \
    DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */                                          \
    DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */                                 \
    DOCTEST_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/                \
    /* */                                                                                          \
    DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */                             \
    DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */                             \
    DOCTEST_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */    \
    DOCTEST_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */             \
    DOCTEST_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \
    DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */                   \
    DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */                                              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */           \
    DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */          \
    DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */  \
    DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */                   \
    /* static analysis */                                                                          \
    DOCTEST_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */       \
    DOCTEST_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */                 \
    DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */                             \
    DOCTEST_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */  \
    DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */

#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP                                                       \
    DOCTEST_CLANG_SUPPRESS_WARNING_POP                                                             \
    DOCTEST_GCC_SUPPRESS_WARNING_POP                                                               \
    DOCTEST_MSVC_SUPPRESS_WARNING_POP

DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH

DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated")

DOCTEST_GCC_SUPPRESS_WARNING_PUSH
DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy")
DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor")
DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo")

DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted

#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN                                 \
    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH                                                             \
    DOCTEST_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */       \
    DOCTEST_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */     \
    DOCTEST_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */      \
    DOCTEST_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */                \
    DOCTEST_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */                  \
    DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */                             \
    DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */                   \
    DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */                                              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */           \
    DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */          \
    DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */              \
    DOCTEST_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */           \
    DOCTEST_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \
    DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */                   \
    DOCTEST_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */

#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP

// =================================================================================================
// == FEATURE DETECTION ============================================================================
// =================================================================================================

// general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support
// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx
// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html
// MSVC version table:
// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering
// MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022)
// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019)
// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017)
// MSVC++ 14.0      _MSC_VER == 1900 (Visual Studio 2015)
// MSVC++ 12.0      _MSC_VER == 1800 (Visual Studio 2013)
// MSVC++ 11.0      _MSC_VER == 1700 (Visual Studio 2012)
// MSVC++ 10.0      _MSC_VER == 1600 (Visual Studio 2010)
// MSVC++ 9.0       _MSC_VER == 1500 (Visual Studio 2008)
// MSVC++ 8.0       _MSC_VER == 1400 (Visual Studio 2005)

// Universal Windows Platform support
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define DOCTEST_CONFIG_NO_WINDOWS_SEH
#endif // WINAPI_FAMILY
#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
#define DOCTEST_CONFIG_WINDOWS_SEH
#endif // MSVC
#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH)
#undef DOCTEST_CONFIG_WINDOWS_SEH
#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH

#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) &&             \
        !defined(__EMSCRIPTEN__)
#define DOCTEST_CONFIG_POSIX_SIGNALS
#endif // _WIN32
#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS)
#undef DOCTEST_CONFIG_POSIX_SIGNALS
#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS

#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND)
#define DOCTEST_CONFIG_NO_EXCEPTIONS
#endif // no exceptions
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS

#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
#define DOCTEST_CONFIG_NO_EXCEPTIONS
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS

#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS)
#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS

#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT)
#define DOCTEST_CONFIG_IMPLEMENT
#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN

#if defined(_WIN32) || defined(__CYGWIN__)
#if DOCTEST_MSVC
#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport)
#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport)
#else // MSVC
#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport))
#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport))
#endif // MSVC
#else  // _WIN32
#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default")))
#define DOCTEST_SYMBOL_IMPORT
#endif // _WIN32

#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
#ifdef DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT
#else // DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT
#endif // DOCTEST_CONFIG_IMPLEMENT
#else  // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL
#define DOCTEST_INTERFACE
#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL

#define DOCTEST_EMPTY

#if DOCTEST_MSVC
#define DOCTEST_NOINLINE __declspec(noinline)
#define DOCTEST_UNUSED
#define DOCTEST_ALIGNMENT(x)
#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
#define DOCTEST_NOINLINE
#define DOCTEST_UNUSED
#define DOCTEST_ALIGNMENT(x)
#else
#define DOCTEST_NOINLINE __attribute__((noinline))
#define DOCTEST_UNUSED __attribute__((unused))
#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
#endif

#ifndef DOCTEST_NORETURN
#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
#define DOCTEST_NORETURN
#else // DOCTEST_MSVC
#define DOCTEST_NORETURN [[noreturn]]
#endif // DOCTEST_MSVC
#endif // DOCTEST_NORETURN

#ifndef DOCTEST_NOEXCEPT
#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
#define DOCTEST_NOEXCEPT
#else // DOCTEST_MSVC
#define DOCTEST_NOEXCEPT noexcept
#endif // DOCTEST_MSVC
#endif // DOCTEST_NOEXCEPT

#ifndef DOCTEST_CONSTEXPR
#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
#define DOCTEST_CONSTEXPR const
#else // DOCTEST_MSVC
#define DOCTEST_CONSTEXPR constexpr
#endif // DOCTEST_MSVC
#endif // DOCTEST_CONSTEXPR

// =================================================================================================
// == FEATURE DETECTION END ========================================================================
// =================================================================================================

// internal macros for string concatenation and anonymous variable name generation
#define DOCTEST_CAT_IMPL(s1, s2) s1##s2
#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2)
#ifdef __COUNTER__ // not standard and may be missing for some compilers
#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__)
#else // __COUNTER__
#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__)
#endif // __COUNTER__

#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
#define DOCTEST_REF_WRAP(x) x&
#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE
#define DOCTEST_REF_WRAP(x) x
#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE

// not using __APPLE__ because... this is how Catch does it
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
#define DOCTEST_PLATFORM_MAC
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#define DOCTEST_PLATFORM_IPHONE
#elif defined(_WIN32)
#define DOCTEST_PLATFORM_WINDOWS
#else // DOCTEST_PLATFORM
#define DOCTEST_PLATFORM_LINUX
#endif // DOCTEST_PLATFORM

namespace doctest { namespace detail {
    static DOCTEST_CONSTEXPR int consume(const int*, int) { return 0; }
}}

#define DOCTEST_GLOBAL_NO_WARNINGS(var, ...)                                                       \
    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors")                              \
    static const int var = doctest::detail::consume(&var, __VA_ARGS__);                            \
    DOCTEST_CLANG_SUPPRESS_WARNING_POP

#ifndef DOCTEST_BREAK_INTO_DEBUGGER
// should probably take a look at https://github.com/scottt/debugbreak
#ifdef DOCTEST_PLATFORM_LINUX
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
// Break at the location of the failing check if possible
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler)
#else
#include <signal.h>
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT (hicpp-no-assembler)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT (hicpp-no-assembler)
#endif
#elif DOCTEST_MSVC
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
#elif defined(__MINGW32__)
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls")
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
#else // linux
#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
#endif // linux
#endif // DOCTEST_BREAK_INTO_DEBUGGER

// this is kept here for backwards compatibility since the config option was changed
#ifdef DOCTEST_CONFIG_USE_IOSFWD
#define DOCTEST_CONFIG_USE_STD_HEADERS
#endif // DOCTEST_CONFIG_USE_IOSFWD

// for clang - always include ciso646 (which drags some std stuff) because
// we want to check if we are using libc++ with the _LIBCPP_VERSION macro in
// which case we don't want to forward declare stuff from std - for reference:
// https://github.com/doctest/doctest/issues/126
// https://github.com/doctest/doctest/issues/356
#if DOCTEST_CLANG
#include <ciso646>
#ifdef _LIBCPP_VERSION
#define DOCTEST_CONFIG_USE_STD_HEADERS
#endif // _LIBCPP_VERSION
#endif // clang

#ifdef DOCTEST_CONFIG_USE_STD_HEADERS
#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#include <cstddef>
#include <ostream>
#include <istream>
#else // DOCTEST_CONFIG_USE_STD_HEADERS

// Forward declaring 'X' in namespace std is not permitted by the C++ Standard.
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643)

namespace std { // NOLINT (cert-dcl58-cpp)
typedef decltype(nullptr) nullptr_t;
template <class charT>
struct char_traits;
template <>
struct char_traits<char>;
template <class charT, class traits>
class basic_ostream;
typedef basic_ostream<char, char_traits<char>> ostream;
template <class charT, class traits>
class basic_istream;
typedef basic_istream<char, char_traits<char>> istream;
template <class... Types>
class tuple;
#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
template <class Ty>
class allocator;
template <class Elem, class Traits, class Alloc>
class basic_string;
using string = basic_string<char, char_traits<char>, allocator<char>>;
#endif // VS 2019
} // namespace std

DOCTEST_MSVC_SUPPRESS_WARNING_POP

#endif // DOCTEST_CONFIG_USE_STD_HEADERS

#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#include <type_traits>
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS

namespace doctest {

DOCTEST_INTERFACE extern bool is_running_in_test;

// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length
// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for:
// - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128)
// - if small - capacity left before going on the heap - using the lowest 5 bits
// - if small - 2 bits are left unused - the second and third highest ones
// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator)
//              and the "is small" bit remains "0" ("as well as the capacity left") so its OK
// Idea taken from this lecture about the string implementation of facebook/folly - fbstring
// https://www.youtube.com/watch?v=kPR8h4-qZdk
// TODO:
// - optimizations - like not deleting memory unnecessarily in operator= and etc.
// - resize/reserve/clear
// - substr
// - replace
// - back/front
// - iterator stuff
// - find & friends
// - push_back/pop_back
// - assign/insert/erase
// - relational operators as free functions - taking const char* as one of the params
class DOCTEST_INTERFACE String
{
    static const unsigned len  = 24;      //!OCLINT avoid private static members
    static const unsigned last = len - 1; //!OCLINT avoid private static members

    struct view // len should be more than sizeof(view) - because of the final byte for flags
    {
        char*    ptr;
        unsigned size;
        unsigned capacity;
    };

    union
    {
        char buf[len];
        view data;
    };

    char* allocate(unsigned sz);

    bool isOnStack() const { return (buf[last] & 128) == 0; }
    void setOnHeap();
    void setLast(unsigned in = last);

    void copy(const String& other);

public:
    String();
    ~String();

    // cppcheck-suppress noExplicitConstructor
    String(const char* in);
    String(const char* in, unsigned in_size);

    String(std::istream& in, unsigned in_size);

    String(const String& other);
    String& operator=(const String& other);

    String& operator+=(const String& other);

    String(String&& other);
    String& operator=(String&& other);

    char  operator[](unsigned i) const;
    char& operator[](unsigned i);

    // the only functions I'm willing to leave in the interface - available for inlining
    const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT
    char*       c_str() {
        if(isOnStack())
            return reinterpret_cast<char*>(buf);
        return data.ptr;
    }

    unsigned size() const;
    unsigned capacity() const;

    int compare(const char* other, bool no_case = false) const;
    int compare(const String& other, bool no_case = false) const;
};

DOCTEST_INTERFACE String operator+(const String& lhs, const String& rhs);

DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs);
DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs);
DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs);
DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs);
DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs);
DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs);

DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in);

namespace Color {
    enum Enum
    {
        None = 0,
        White,
        Red,
        Green,
        Blue,
        Cyan,
        Yellow,
        Grey,

        Bright = 0x10,

        BrightRed   = Bright | Red,
        BrightGreen = Bright | Green,
        LightGrey   = Bright | Grey,
        BrightWhite = Bright | White
    };

    DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code);
} // namespace Color

namespace assertType {
    enum Enum
    {
        // macro traits

        is_warn    = 1,
        is_check   = 2 * is_warn,
        is_require = 2 * is_check,

        is_normal      = 2 * is_require,
        is_throws      = 2 * is_normal,
        is_throws_as   = 2 * is_throws,
        is_throws_with = 2 * is_throws_as,
        is_nothrow     = 2 * is_throws_with,

        is_false = 2 * is_nothrow,
        is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types

        is_eq = 2 * is_unary,
        is_ne = 2 * is_eq,

        is_lt = 2 * is_ne,
        is_gt = 2 * is_lt,

        is_ge = 2 * is_gt,
        is_le = 2 * is_ge,

        // macro types

        DT_WARN    = is_normal | is_warn,
        DT_CHECK   = is_normal | is_check,
        DT_REQUIRE = is_normal | is_require,

        DT_WARN_FALSE    = is_normal | is_false | is_warn,
        DT_CHECK_FALSE   = is_normal | is_false | is_check,
        DT_REQUIRE_FALSE = is_normal | is_false | is_require,

        DT_WARN_THROWS    = is_throws | is_warn,
        DT_CHECK_THROWS   = is_throws | is_check,
        DT_REQUIRE_THROWS = is_throws | is_require,

        DT_WARN_THROWS_AS    = is_throws_as | is_warn,
        DT_CHECK_THROWS_AS   = is_throws_as | is_check,
        DT_REQUIRE_THROWS_AS = is_throws_as | is_require,

        DT_WARN_THROWS_WITH    = is_throws_with | is_warn,
        DT_CHECK_THROWS_WITH   = is_throws_with | is_check,
        DT_REQUIRE_THROWS_WITH = is_throws_with | is_require,
        
        DT_WARN_THROWS_WITH_AS    = is_throws_with | is_throws_as | is_warn,
        DT_CHECK_THROWS_WITH_AS   = is_throws_with | is_throws_as | is_check,
        DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require,

        DT_WARN_NOTHROW    = is_nothrow | is_warn,
        DT_CHECK_NOTHROW   = is_nothrow | is_check,
        DT_REQUIRE_NOTHROW = is_nothrow | is_require,

        DT_WARN_EQ    = is_normal | is_eq | is_warn,
        DT_CHECK_EQ   = is_normal | is_eq | is_check,
        DT_REQUIRE_EQ = is_normal | is_eq | is_require,

        DT_WARN_NE    = is_normal | is_ne | is_warn,
        DT_CHECK_NE   = is_normal | is_ne | is_check,
        DT_REQUIRE_NE = is_normal | is_ne | is_require,

        DT_WARN_GT    = is_normal | is_gt | is_warn,
        DT_CHECK_GT   = is_normal | is_gt | is_check,
        DT_REQUIRE_GT = is_normal | is_gt | is_require,

        DT_WARN_LT    = is_normal | is_lt | is_warn,
        DT_CHECK_LT   = is_normal | is_lt | is_check,
        DT_REQUIRE_LT = is_normal | is_lt | is_require,

        DT_WARN_GE    = is_normal | is_ge | is_warn,
        DT_CHECK_GE   = is_normal | is_ge | is_check,
        DT_REQUIRE_GE = is_normal | is_ge | is_require,

        DT_WARN_LE    = is_normal | is_le | is_warn,
        DT_CHECK_LE   = is_normal | is_le | is_check,
        DT_REQUIRE_LE = is_normal | is_le | is_require,

        DT_WARN_UNARY    = is_normal | is_unary | is_warn,
        DT_CHECK_UNARY   = is_normal | is_unary | is_check,
        DT_REQUIRE_UNARY = is_normal | is_unary | is_require,

        DT_WARN_UNARY_FALSE    = is_normal | is_false | is_unary | is_warn,
        DT_CHECK_UNARY_FALSE   = is_normal | is_false | is_unary | is_check,
        DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require,
    };
} // namespace assertType

DOCTEST_INTERFACE const char* assertString(assertType::Enum at);
DOCTEST_INTERFACE const char* failureString(assertType::Enum at);
DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);

struct DOCTEST_INTERFACE TestCaseData
{
    String      m_file;       // the file in which the test was registered (using String - see #350)
    unsigned    m_line;       // the line where the test was registered
    const char* m_name;       // name of the test case
    const char* m_test_suite; // the test suite in which the test was added
    const char* m_description;
    bool        m_skip;
    bool        m_no_breaks;
    bool        m_no_output;
    bool        m_may_fail;
    bool        m_should_fail;
    int         m_expected_failures;
    double      m_timeout;
};

struct DOCTEST_INTERFACE AssertData
{
    // common - for all asserts
    const TestCaseData* m_test_case;
    assertType::Enum    m_at;
    const char*         m_file;
    int                 m_line;
    const char*         m_expr;
    bool                m_failed;

    // exception-related - for all asserts
    bool   m_threw;
    String m_exception;

    // for normal asserts
    String m_decomp;

    // for specific exception-related asserts
    bool        m_threw_as;
    const char* m_exception_type;
    const char* m_exception_string;
};

struct DOCTEST_INTERFACE MessageData
{
    String           m_string;
    const char*      m_file;
    int              m_line;
    assertType::Enum m_severity;
};

struct DOCTEST_INTERFACE SubcaseSignature
{
    String      m_name;
    const char* m_file;
    int         m_line;

    bool operator<(const SubcaseSignature& other) const;
};

struct DOCTEST_INTERFACE IContextScope
{
    IContextScope();
    virtual ~IContextScope();
    virtual void stringify(std::ostream*) const = 0;
};

namespace detail {
    struct DOCTEST_INTERFACE TestCase;
} // namespace detail

struct ContextOptions //!OCLINT too many fields
{
    std::ostream* cout = nullptr; // stdout stream
    String        binary_name;    // the test binary name

    const detail::TestCase* currentTest = nullptr;

    // == parameters from the command line
    String   out;       // output filename
    String   order_by;  // how tests should be ordered
    unsigned rand_seed; // the seed for rand ordering

    unsigned first; // the first (matching) test to be executed
    unsigned last;  // the last (matching) test to be executed

    int abort_after;           // stop tests after this many failed assertions
    int subcase_filter_levels; // apply the subcase filters for the first N levels

    bool success;              // include successful assertions in output
    bool case_sensitive;       // if filtering should be case sensitive
    bool exit;                 // if the program should be exited after the tests are ran/whatever
    bool duration;             // print the time duration of each test case
    bool minimal;              // minimal console output (only test failures)
    bool quiet;                // no console output
    bool no_throw;             // to skip exceptions-related assertion macros
    bool no_exitcode;          // if the framework should return 0 as the exitcode
    bool no_run;               // to not run the tests at all (can be done with an "*" exclude)
    bool no_intro;             // to not print the intro of the framework
    bool no_version;           // to not print the version of the framework
    bool no_colors;            // if output to the console should be colorized
    bool force_colors;         // forces the use of colors even when a tty cannot be detected
    bool no_breaks;            // to not break into the debugger
    bool no_skip;              // don't skip test cases which are marked to be skipped
    bool gnu_file_line;        // if line numbers should be surrounded with :x: and not (x):
    bool no_path_in_filenames; // if the path to files should be removed from the output
    bool no_line_numbers;      // if source code line numbers should be omitted from the output
    bool no_debug_output;      // no output in the debug console when a debugger is attached
    bool no_skipped_summary;   // don't print "skipped" in the summary !!! UNDOCUMENTED !!!
    bool no_time_in_output;    // omit any time/timestamps from output !!! UNDOCUMENTED !!!

    bool help;             // to print the help
    bool version;          // to print the version
    bool count;            // if only the count of matching tests is to be retrieved
    bool list_test_cases;  // to list all tests matching the filters
    bool list_test_suites; // to list all suites matching the filters
    bool list_reporters;   // lists all registered reporters
};

namespace detail {
    template <bool CONDITION, typename TYPE = void>
    struct enable_if
    {};

    template <typename TYPE>
    struct enable_if<true, TYPE>
    { typedef TYPE type; };

    // clang-format off
    template<class T> struct remove_reference      { typedef T type; };
    template<class T> struct remove_reference<T&>  { typedef T type; };
    template<class T> struct remove_reference<T&&> { typedef T type; };

    template<typename T, typename U = T&&> U declval(int); 

    template<typename T> T declval(long); 

    template<typename T> auto declval() DOCTEST_NOEXCEPT -> decltype(declval<T>(0)) ;

    template<class T> struct is_lvalue_reference { const static bool value=false; };
    template<class T> struct is_lvalue_reference<T&> { const static bool value=true; };

    template<class T> struct is_rvalue_reference { const static bool value=false; };
    template<class T> struct is_rvalue_reference<T&&> { const static bool value=true; };

    template <class T>
    inline T&& forward(typename remove_reference<T>::type& t) DOCTEST_NOEXCEPT
    {
        return static_cast<T&&>(t);
    }

    template <class T>
    inline T&& forward(typename remove_reference<T>::type&& t) DOCTEST_NOEXCEPT
    {
        static_assert(!is_lvalue_reference<T>::value,
                        "Can not forward an rvalue as an lvalue.");
        return static_cast<T&&>(t);
    }

    template<class T> struct remove_const          { typedef T type; };
    template<class T> struct remove_const<const T> { typedef T type; };
#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
    template<class T> struct is_enum : public std::is_enum<T> {};
    template<class T> struct underlying_type : public std::underlying_type<T> {};
#else
    // Use compiler intrinsics
    template<class T> struct is_enum { DOCTEST_CONSTEXPR static bool value = __is_enum(T); };
    template<class T> struct underlying_type { typedef __underlying_type(T) type; };
#endif
    // clang-format on

    template <typename T>
    struct deferred_false
    // cppcheck-suppress unusedStructMember
    { static const bool value = false; };

    namespace has_insertion_operator_impl {
        std::ostream &os();
        template<class T>
        DOCTEST_REF_WRAP(T) val();

        template<class, class = void>
        struct check {
            static DOCTEST_CONSTEXPR bool value = false;
        };

        template<class T>
        struct check<T, decltype(os() << val<T>(), void())> {
            static DOCTEST_CONSTEXPR bool value = true;
        };
    } // namespace has_insertion_operator_impl

    template<class T>
    using has_insertion_operator = has_insertion_operator_impl::check<const T>;

    DOCTEST_INTERFACE std::ostream* tlssPush();
    DOCTEST_INTERFACE String tlssPop();


    template <bool C>
    struct StringMakerBase
    {
        template <typename T>
        static String convert(const DOCTEST_REF_WRAP(T)) {
            return "{?}";
        }
    };

    // Vector<int> and various type other than pointer or array.
    template<typename T>
    struct filldata
    {
        static void fill(std::ostream* stream, const T &in) {
          *stream << in;
        }
    };

    template<typename T,unsigned long N>
    struct filldata<T[N]>
    {
        static void fill(std::ostream* stream, const T (&in)[N]) {
            for (unsigned long i = 0; i < N; i++) {
                *stream << in[i];
            }
        }
    };

    // Specialized since we don't want the terminating null byte!
    template<unsigned long N>
    struct filldata<const char[N]>
    {
        static void fill(std::ostream* stream, const char(&in)[N]) {
            *stream << in;
        }
    };

    template<typename T>
    void filloss(std::ostream* stream, const T& in) {
        filldata<T>::fill(stream, in);
    }

    template<typename T,unsigned long N>
    void filloss(std::ostream* stream, const T (&in)[N]) {
        // T[N], T(&)[N], T(&&)[N] have same behaviour.
        // Hence remove reference.
        filldata<typename remove_reference<decltype(in)>::type>::fill(stream, in);
    }

    template <>
    struct StringMakerBase<true>
    {
        template <typename T>
        static String convert(const DOCTEST_REF_WRAP(T) in) {
            /* When parameter "in" is a null terminated const char* it works.
             * When parameter "in" is a T arr[N] without '\0' we can fill the
             * stringstream with N objects (T=char).If in is char pointer *
             * without '\0' , it would cause segfault
             * stepping over unaccessible memory.
             */

            std::ostream* stream = tlssPush();
            filloss(stream, in);
            return tlssPop();
        }
    };

    DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size);

    template <typename T>
    String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) {
        return rawMemoryToString(&object, sizeof(object));
    }

    template <typename T>
    const char* type_to_string() {
        return "<>";
    }
} // namespace detail

template <typename T>
struct StringMaker : public detail::StringMakerBase<detail::has_insertion_operator<T>::value>
{};

template <typename T>
struct StringMaker<T*>
{
    template <typename U>
    static String convert(U* p) {
        if(p)
            return detail::rawMemoryToString(p);
        return "NULL";
    }
};

template <typename R, typename C>
struct StringMaker<R C::*>
{
    static String convert(R C::*p) {
        if(p)
            return detail::rawMemoryToString(p);
        return "NULL";
    }
};

template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
String toString(const DOCTEST_REF_WRAP(T) value) {
    return StringMaker<T>::convert(value);
}

#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
DOCTEST_INTERFACE String toString(char* in);
DOCTEST_INTERFACE String toString(const char* in);
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
DOCTEST_INTERFACE String toString(bool in);
DOCTEST_INTERFACE String toString(float in);
DOCTEST_INTERFACE String toString(double in);
DOCTEST_INTERFACE String toString(double long in);

DOCTEST_INTERFACE String toString(char in);
DOCTEST_INTERFACE String toString(char signed in);
DOCTEST_INTERFACE String toString(char unsigned in);
DOCTEST_INTERFACE String toString(int short in);
DOCTEST_INTERFACE String toString(int short unsigned in);
DOCTEST_INTERFACE String toString(int in);
DOCTEST_INTERFACE String toString(int unsigned in);
DOCTEST_INTERFACE String toString(int long in);
DOCTEST_INTERFACE String toString(int long unsigned in);
DOCTEST_INTERFACE String toString(int long long in);
DOCTEST_INTERFACE String toString(int long long unsigned in);
DOCTEST_INTERFACE String toString(std::nullptr_t in);

template <typename T, typename detail::enable_if<detail::is_enum<T>::value, bool>::type = true>
String toString(const DOCTEST_REF_WRAP(T) value) {
    typedef typename detail::underlying_type<T>::type UT;
    return toString(static_cast<UT>(value));
}

#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
DOCTEST_INTERFACE String toString(const std::string& in);
#endif // VS 2019

class DOCTEST_INTERFACE Approx
{
public:
    explicit Approx(double value);

    Approx operator()(double value) const;

#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
    template <typename T>
    explicit Approx(const T& value,
                    typename detail::enable_if<std::is_constructible<double, T>::value>::type* =
                            static_cast<T*>(nullptr)) {
        *this = Approx(static_cast<double>(value));
    }
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS

    Approx& epsilon(double newEpsilon);

#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
    template <typename T>
    typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(
            const T& newEpsilon) {
        m_epsilon = static_cast<double>(newEpsilon);
        return *this;
    }
#endif //  DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS

    Approx& scale(double newScale);

#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
    template <typename T>
    typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(
            const T& newScale) {
        m_scale = static_cast<double>(newScale);
        return *this;
    }
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS

    // clang-format off
    DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs);
    DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs);
    DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs);
    DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs);
    DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs);
    DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs);
    DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs);

    DOCTEST_INTERFACE friend String toString(const Approx& in);

#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#define DOCTEST_APPROX_PREFIX \
    template <typename T> friend typename detail::enable_if<std::is_constructible<double, T>::value, bool>::type

    DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); }
    DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }
    DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
    DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); }
    DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; }
    DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; }
    DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; }
    DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; }
    DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; }
    DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; }
    DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; }
    DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; }
#undef DOCTEST_APPROX_PREFIX
#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS

    // clang-format on

private:
    double m_epsilon;
    double m_scale;
    double m_value;
};

DOCTEST_INTERFACE String toString(const Approx& in);

DOCTEST_INTERFACE const ContextOptions* getContextOptions();

#if !defined(DOCTEST_CONFIG_DISABLE)

namespace detail {
    // clang-format off
#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
    template<class T>               struct decay_array       { typedef T type; };
    template<class T, unsigned N>   struct decay_array<T[N]> { typedef T* type; };
    template<class T>               struct decay_array<T[]>  { typedef T* type; };

    template<class T>   struct not_char_pointer              { enum { value = 1 }; };
    template<>          struct not_char_pointer<char*>       { enum { value = 0 }; };
    template<>          struct not_char_pointer<const char*> { enum { value = 0 }; };

    template<class T> struct can_use_op : public not_char_pointer<typename decay_array<T>::type> {};
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
    // clang-format on

    struct DOCTEST_INTERFACE TestFailureException
    {
    };

    DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at);

#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
    DOCTEST_NORETURN
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
    DOCTEST_INTERFACE void throwException();

    struct DOCTEST_INTERFACE Subcase
    {
        SubcaseSignature m_signature;
        bool             m_entered = false;

        Subcase(const String& name, const char* file, int line);
        ~Subcase();

        operator bool() const;
    };

    template <typename L, typename R>
    String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op,
                               const DOCTEST_REF_WRAP(R) rhs) {
        // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
        return toString(lhs) + op + toString(rhs);
    }

#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison")
#endif

// This will check if there is any way it could find a operator like member or friend and uses it.
// If not it doesn't find the operator or if the operator at global scope is defined after
// this template, the template won't be instantiated due to SFINAE. Once the template is not
// instantiated it can look for global operator using normal conversions.
#define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval<L>() op doctest::detail::declval<R>()),ret{})

#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro)                              \
    template <typename R>                                                                          \
    DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R&& rhs) {                             \
    bool res = op_macro(doctest::detail::forward<const L>(lhs), doctest::detail::forward<const R>(rhs));                                                             \
        if(m_at & assertType::is_false)                                                            \
            res = !res;                                                                            \
        if(!res || doctest::getContextOptions()->success)                                          \
            return Result(res, stringifyBinaryExpr(lhs, op_str, rhs));                             \
        return Result(res);                                                                        \
    }                                                                                              \
    template <typename R ,typename enable_if<!doctest::detail::is_rvalue_reference<R>::value, void >::type* = nullptr> \
    DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(const R& rhs) {                              \
    bool res = op_macro(doctest::detail::forward<const L>(lhs), rhs);                              \
        if(m_at & assertType::is_false)                                                            \
            res = !res;                                                                            \
        if(!res || doctest::getContextOptions()->success)                                          \
            return Result(res, stringifyBinaryExpr(lhs, op_str, rhs));                             \
        return Result(res);                                                                        \
    }

    // more checks could be added - like in Catch:
    // https://github.com/catchorg/Catch2/pull/1480/files
    // https://github.com/catchorg/Catch2/pull/1481/files
#define DOCTEST_FORBIT_EXPRESSION(rt, op)                                                          \
    template <typename R>                                                                          \
    rt& operator op(const R&) {                                                                    \
        static_assert(deferred_false<R>::value,                                                    \
                      "Expression Too Complex Please Rewrite As Binary Comparison!");              \
        return *this;                                                                              \
    }

    struct DOCTEST_INTERFACE Result
    {
        bool   m_passed;
        String m_decomp;

        Result() = default;
        Result(bool passed, const String& decomposition = String());

        // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
        DOCTEST_FORBIT_EXPRESSION(Result, &)
        DOCTEST_FORBIT_EXPRESSION(Result, ^)
        DOCTEST_FORBIT_EXPRESSION(Result, |)
        DOCTEST_FORBIT_EXPRESSION(Result, &&)
        DOCTEST_FORBIT_EXPRESSION(Result, ||)
        DOCTEST_FORBIT_EXPRESSION(Result, ==)
        DOCTEST_FORBIT_EXPRESSION(Result, !=)
        DOCTEST_FORBIT_EXPRESSION(Result, <)
        DOCTEST_FORBIT_EXPRESSION(Result, >)
        DOCTEST_FORBIT_EXPRESSION(Result, <=)
        DOCTEST_FORBIT_EXPRESSION(Result, >=)
        DOCTEST_FORBIT_EXPRESSION(Result, =)
        DOCTEST_FORBIT_EXPRESSION(Result, +=)
        DOCTEST_FORBIT_EXPRESSION(Result, -=)
        DOCTEST_FORBIT_EXPRESSION(Result, *=)
        DOCTEST_FORBIT_EXPRESSION(Result, /=)
        DOCTEST_FORBIT_EXPRESSION(Result, %=)
        DOCTEST_FORBIT_EXPRESSION(Result, <<=)
        DOCTEST_FORBIT_EXPRESSION(Result, >>=)
        DOCTEST_FORBIT_EXPRESSION(Result, &=)
        DOCTEST_FORBIT_EXPRESSION(Result, ^=)
        DOCTEST_FORBIT_EXPRESSION(Result, |=)
    };

#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION

    DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
    DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare")
    //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion")
    //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion")
    //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal")

    DOCTEST_GCC_SUPPRESS_WARNING_PUSH
    DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
    DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare")
    //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion")
    //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
    //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal")

    DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
    // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389
    DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch
    DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch
    DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch
    //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation

#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION

    // clang-format off
#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_COMPARISON_RETURN_TYPE bool
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
    inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
    inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
    inline bool lt(const char* lhs, const char* rhs) { return String(lhs) <  String(rhs); }
    inline bool gt(const char* lhs, const char* rhs) { return String(lhs) >  String(rhs); }
    inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); }
    inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); }
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
    // clang-format on

#define DOCTEST_RELATIONAL_OP(name, op)                                                            \
    template <typename L, typename R>                                                              \
    DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs,                             \
                                        const DOCTEST_REF_WRAP(R) rhs) {                           \
        return lhs op rhs;                                                                         \
    }

    DOCTEST_RELATIONAL_OP(eq, ==)
    DOCTEST_RELATIONAL_OP(ne, !=)
    DOCTEST_RELATIONAL_OP(lt, <)
    DOCTEST_RELATIONAL_OP(gt, >)
    DOCTEST_RELATIONAL_OP(le, <=)
    DOCTEST_RELATIONAL_OP(ge, >=)

#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_CMP_EQ(l, r) l == r
#define DOCTEST_CMP_NE(l, r) l != r
#define DOCTEST_CMP_GT(l, r) l > r
#define DOCTEST_CMP_LT(l, r) l < r
#define DOCTEST_CMP_GE(l, r) l >= r
#define DOCTEST_CMP_LE(l, r) l <= r
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_CMP_EQ(l, r) eq(l, r)
#define DOCTEST_CMP_NE(l, r) ne(l, r)
#define DOCTEST_CMP_GT(l, r) gt(l, r)
#define DOCTEST_CMP_LT(l, r) lt(l, r)
#define DOCTEST_CMP_GE(l, r) ge(l, r)
#define DOCTEST_CMP_LE(l, r) le(l, r)
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING

    template <typename L>
    // cppcheck-suppress copyCtorAndEqOperator
    struct Expression_lhs
    {
        L                lhs;
        assertType::Enum m_at;

        explicit Expression_lhs(L&& in, assertType::Enum at)
                : lhs(doctest::detail::forward<L>(in))
                , m_at(at) {}

        DOCTEST_NOINLINE operator Result() {
// this is needed only for MSVC 2015
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool
            bool res = static_cast<bool>(lhs);
DOCTEST_MSVC_SUPPRESS_WARNING_POP
            if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional
                res = !res;

            if(!res || getContextOptions()->success)
                return Result(res, toString(lhs));
            return Result(res);
        }

        /* This is required for user-defined conversions from Expression_lhs to L */
        operator L() const { return lhs; }

        // clang-format off
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>,  " >  ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<,  " <  ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional
        DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional
        // clang-format on

        // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=)
        // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the
        // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression...
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<)
        DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>)
    };

#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION

    DOCTEST_CLANG_SUPPRESS_WARNING_POP
    DOCTEST_MSVC_SUPPRESS_WARNING_POP
    DOCTEST_GCC_SUPPRESS_WARNING_POP

#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION

#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_POP
#endif

    struct DOCTEST_INTERFACE ExpressionDecomposer
    {
        assertType::Enum m_at;

        ExpressionDecomposer(assertType::Enum at);

        // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table)
        // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now...
        // https://github.com/catchorg/Catch2/issues/870
        // https://github.com/catchorg/Catch2/issues/565
        template <typename L>
        Expression_lhs<const L> operator<<(const L &&operand) {
            return Expression_lhs<const L>(doctest::detail::forward<const L>(operand), m_at);
        }

        template <typename L,typename enable_if<!doctest::detail::is_rvalue_reference<L>::value,void >::type* = nullptr>
        Expression_lhs<const L&> operator<<(const L &operand) {
            return Expression_lhs<const L&>(operand, m_at);
        }
    };

    struct DOCTEST_INTERFACE TestSuite
    {
        const char* m_test_suite = nullptr;
        const char* m_description = nullptr;
        bool        m_skip = false;
        bool        m_no_breaks = false;
        bool        m_no_output = false;
        bool        m_may_fail = false;
        bool        m_should_fail = false;
        int         m_expected_failures = 0;
        double      m_timeout = 0;

        TestSuite& operator*(const char* in);

        template <typename T>
        TestSuite& operator*(const T& in) {
            in.fill(*this);
            return *this;
        }
    };

    typedef void (*funcType)();

    struct DOCTEST_INTERFACE TestCase : public TestCaseData
    {
        funcType m_test; // a function pointer to the test case

        const char* m_type; // for templated test cases - gets appended to the real name
        int m_template_id; // an ID used to distinguish between the different versions of a templated test case
        String m_full_name; // contains the name (only for templated test cases!) + the template type

        TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
                 const char* type = "", int template_id = -1);

        TestCase(const TestCase& other);

        DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
        TestCase& operator=(const TestCase& other);
        DOCTEST_MSVC_SUPPRESS_WARNING_POP

        TestCase& operator*(const char* in);

        template <typename T>
        TestCase& operator*(const T& in) {
            in.fill(*this);
            return *this;
        }

        bool operator<(const TestCase& other) const;
    };

    // forward declarations of functions used by the macros
    DOCTEST_INTERFACE int  regTest(const TestCase& tc);
    DOCTEST_INTERFACE int  setTestSuite(const TestSuite& ts);
    DOCTEST_INTERFACE bool isDebuggerActive();

    template<typename T>
    int instantiationHelper(const T&) { return 0; }

    namespace binaryAssertComparison {
        enum Enum
        {
            eq = 0,
            ne,
            gt,
            lt,
            ge,
            le
        };
    } // namespace binaryAssertComparison

    // clang-format off
    template <int, class L, class R> struct RelationalComparator     { bool operator()(const DOCTEST_REF_WRAP(L),     const DOCTEST_REF_WRAP(R)    ) const { return false;        } };

#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \
    template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
    // clang-format on

    DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
    DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
    DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
    DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
    DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
    DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)

    struct DOCTEST_INTERFACE ResultBuilder : public AssertData
    {
        ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr,
                      const char* exception_type = "", const char* exception_string = "");

        void setResult(const Result& res);

        template <int comparison, typename L, typename R>
        DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs,
                                            const DOCTEST_REF_WRAP(R) rhs) {
            m_failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);
            if(m_failed || getContextOptions()->success)
                m_decomp = stringifyBinaryExpr(lhs, ", ", rhs);
            return !m_failed;
        }

        template <typename L>
        DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) {
            m_failed = !val;

            if(m_at & assertType::is_false) //!OCLINT bitwise operator in conditional
                m_failed = !m_failed;

            if(m_failed || getContextOptions()->success)
                m_decomp = toString(val);

            return !m_failed;
        }

        void translateException();

        bool log();
        void react() const;
    };

    namespace assertAction {
        enum Enum
        {
            nothing     = 0,
            dbgbreak    = 1,
            shouldthrow = 2
        };
    } // namespace assertAction

    DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad);

    DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char* file, int line,
                                         const char* expr, Result result);

#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp)                                                        \
    do {                                                                                           \
        if(!is_running_in_test) {                                                                  \
            if(failed) {                                                                           \
                ResultBuilder rb(at, file, line, expr);                                            \
                rb.m_failed = failed;                                                              \
                rb.m_decomp = decomp;                                                              \
                failed_out_of_a_testing_context(rb);                                               \
                if(isDebuggerActive() && !getContextOptions()->no_breaks)                          \
                    DOCTEST_BREAK_INTO_DEBUGGER();                                                 \
                if(checkIfShouldThrow(at))                                                         \
                    throwException();                                                              \
            }                                                                                      \
            return !failed;                                                                        \
        }                                                                                          \
    } while(false)

#define DOCTEST_ASSERT_IN_TESTS(decomp)                                                            \
    ResultBuilder rb(at, file, line, expr);                                                        \
    rb.m_failed = failed;                                                                          \
    if(rb.m_failed || getContextOptions()->success)                                                \
        rb.m_decomp = decomp;                                                                      \
    if(rb.log())                                                                                   \
        DOCTEST_BREAK_INTO_DEBUGGER();                                                             \
    if(rb.m_failed && checkIfShouldThrow(at))                                                      \
    throwException()

    template <int comparison, typename L, typename R>
    DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char* file, int line,
                                        const char* expr, const DOCTEST_REF_WRAP(L) lhs,
                                        const DOCTEST_REF_WRAP(R) rhs) {
        bool failed = !RelationalComparator<comparison, L, R>()(lhs, rhs);

        // ###################################################################################
        // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
        // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
        // ###################################################################################
        DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
        DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs));
        return !failed;
    }

    template <typename L>
    DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char* file, int line,
                                       const char* expr, const DOCTEST_REF_WRAP(L) val) {
        bool failed = !val;

        if(at & assertType::is_false) //!OCLINT bitwise operator in conditional
            failed = !failed;

        // ###################################################################################
        // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT
        // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED
        // ###################################################################################
        DOCTEST_ASSERT_OUT_OF_TESTS(toString(val));
        DOCTEST_ASSERT_IN_TESTS(toString(val));
        return !failed;
    }

    struct DOCTEST_INTERFACE IExceptionTranslator
    {
        IExceptionTranslator();
        virtual ~IExceptionTranslator();
        virtual bool translate(String&) const = 0;
    };

    template <typename T>
    class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class
    {
    public:
        explicit ExceptionTranslator(String (*translateFunction)(T))
                : m_translateFunction(translateFunction) {}

        bool translate(String& res) const override {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
            try {
                throw; // lgtm [cpp/rethrow-no-exception]
                // cppcheck-suppress catchExceptionByValue
            } catch(T ex) {                    // NOLINT
                res = m_translateFunction(ex); //!OCLINT parameter reassignment
                return true;
            } catch(...) {}         //!OCLINT -  empty catch statement
#endif                              // DOCTEST_CONFIG_NO_EXCEPTIONS
            static_cast<void>(res); // to silence -Wunused-parameter
            return false;
        }

    private:
        String (*m_translateFunction)(T);
    };

    DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);

    template <bool C>
    struct StringStreamBase
    {
        template <typename T>
        static void convert(std::ostream* s, const T& in) {
            *s << toString(in);
        }

        // always treat char* as a string in this context - no matter
        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
        static void convert(std::ostream* s, const char* in) { *s << String(in); }
    };

    template <>
    struct StringStreamBase<true>
    {
        template <typename T>
        static void convert(std::ostream* s, const T& in) {
            *s << in;
        }
    };

    template <typename T>
    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
    {};

    template <typename T>
    void toStream(std::ostream* s, const T& value) {
        StringStream<T>::convert(s, value);
    }

#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);

    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);

    // ContextScope base class used to allow implementing methods of ContextScope 
    // that don't depend on the template parameter in doctest.cpp.
    class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
    protected:
        ContextScopeBase();
        ContextScopeBase(ContextScopeBase&& other);

        void destroy();
        bool need_to_destroy{true};
    };

    template <typename L> class ContextScope : public ContextScopeBase
    {
        const L lambda_;

    public:
        explicit ContextScope(const L &lambda) : lambda_(lambda) {}

        ContextScope(ContextScope &&other) : ContextScopeBase(static_cast<ContextScopeBase&&>(other)), lambda_(other.lambda_) {}

        void stringify(std::ostream* s) const override { lambda_(s); }

        ~ContextScope() override {
            if (need_to_destroy) {
                destroy();
            }
        }
    };

    struct DOCTEST_INTERFACE MessageBuilder : public MessageData
    {
        std::ostream* m_stream;
        bool          logged = false;

        MessageBuilder(const char* file, int line, assertType::Enum severity);
        MessageBuilder() = delete;
        ~MessageBuilder();

        // the preferred way of chaining parameters for stringification
        template <typename T>
        MessageBuilder& operator,(const T& in) {
            toStream(m_stream, in);
            return *this;
        }

        // kept here just for backwards-compatibility - the comma operator should be preferred now
        template <typename T>
        MessageBuilder& operator<<(const T& in) { return this->operator,(in); }

        // the `,` operator has the lowest operator precedence - if `<<` is used by the user then
        // the `,` operator will be called last which is not what we want and thus the `*` operator
        // is used first (has higher operator precedence compared to `<<`) so that we guarantee that
        // an operator of the MessageBuilder class is called first before the rest of the parameters
        template <typename T>
        MessageBuilder& operator*(const T& in) { return this->operator,(in); }

        bool log();
        void react();
    };
    
    template <typename L>
    ContextScope<L> MakeContextScope(const L &lambda) {
        return ContextScope<L>(lambda);
    }
} // namespace detail

#define DOCTEST_DEFINE_DECORATOR(name, type, def)                                                  \
    struct name                                                                                    \
    {                                                                                              \
        type data;                                                                                 \
        name(type in = def)                                                                        \
                : data(in) {}                                                                      \
        void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; }           \
        void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; }          \
    }

DOCTEST_DEFINE_DECORATOR(test_suite, const char*, "");
DOCTEST_DEFINE_DECORATOR(description, const char*, "");
DOCTEST_DEFINE_DECORATOR(skip, bool, true);
DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true);
DOCTEST_DEFINE_DECORATOR(no_output, bool, true);
DOCTEST_DEFINE_DECORATOR(timeout, double, 0);
DOCTEST_DEFINE_DECORATOR(may_fail, bool, true);
DOCTEST_DEFINE_DECORATOR(should_fail, bool, true);
DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0);

template <typename T>
int registerExceptionTranslator(String (*translateFunction)(T)) {
    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors")
    static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction);
    DOCTEST_CLANG_SUPPRESS_WARNING_POP
    detail::registerExceptionTranslatorImpl(&exceptionTranslator);
    return 0;
}

} // namespace doctest

// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro
// introduces an anonymous namespace in which getCurrentTestSuite gets overridden
namespace doctest_detail_test_suite_ns {
DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite();
} // namespace doctest_detail_test_suite_ns

namespace doctest {
#else  // DOCTEST_CONFIG_DISABLE
template <typename T>
int registerExceptionTranslator(String (*)(T)) {
    return 0;
}
#endif // DOCTEST_CONFIG_DISABLE

namespace detail {
    typedef void (*assert_handler)(const AssertData&);
    struct ContextState;
} // namespace detail

class DOCTEST_INTERFACE Context
{
    detail::ContextState* p;

    void parseArgs(int argc, const char* const* argv, bool withDefaults = false);

public:
    explicit Context(int argc = 0, const char* const* argv = nullptr);

    ~Context();

    void applyCommandLine(int argc, const char* const* argv);

    void addFilter(const char* filter, const char* value);
    void clearFilters();
    void setOption(const char* option, bool value);
    void setOption(const char* option, int value);
    void setOption(const char* option, const char* value);

    bool shouldExit();

    void setAsDefaultForAssertsOutOfTestCases();

    void setAssertHandler(detail::assert_handler ah);

    void setCout(std::ostream* out);

    int run();
};

namespace TestCaseFailureReason {
    enum Enum
    {
        None                     = 0,
        AssertFailure            = 1,   // an assertion has failed in the test case
        Exception                = 2,   // test case threw an exception
        Crash                    = 4,   // a crash...
        TooManyFailedAsserts     = 8,   // the abort-after option
        Timeout                  = 16,  // see the timeout decorator
        ShouldHaveFailedButDidnt = 32,  // see the should_fail decorator
        ShouldHaveFailedAndDid   = 64,  // see the should_fail decorator
        DidntFailExactlyNumTimes = 128, // see the expected_failures decorator
        FailedExactlyNumTimes    = 256, // see the expected_failures decorator
        CouldHaveFailedAndDid    = 512  // see the may_fail decorator
    };
} // namespace TestCaseFailureReason

struct DOCTEST_INTERFACE CurrentTestCaseStats
{
    int    numAssertsCurrentTest;
    int    numAssertsFailedCurrentTest;
    double seconds;
    int    failure_flags; // use TestCaseFailureReason::Enum
    bool   testCaseSuccess;
};

struct DOCTEST_INTERFACE TestCaseException
{
    String error_string;
    bool   is_crash;
};

struct DOCTEST_INTERFACE TestRunStats
{
    unsigned numTestCases;
    unsigned numTestCasesPassingFilters;
    unsigned numTestSuitesPassingFilters;
    unsigned numTestCasesFailed;
    int      numAsserts;
    int      numAssertsFailed;
};

struct QueryData
{
    const TestRunStats*  run_stats = nullptr;
    const TestCaseData** data      = nullptr;
    unsigned             num_data  = 0;
};

struct DOCTEST_INTERFACE IReporter
{
    // The constructor has to accept "const ContextOptions&" as a single argument
    // which has most of the options for the run + a pointer to the stdout stream
    // Reporter(const ContextOptions& in)

    // called when a query should be reported (listing test cases, printing the version, etc.)
    virtual void report_query(const QueryData&) = 0;

    // called when the whole test run starts
    virtual void test_run_start() = 0;
    // called when the whole test run ends (caching a pointer to the input doesn't make sense here)
    virtual void test_run_end(const TestRunStats&) = 0;

    // called when a test case is started (safe to cache a pointer to the input)
    virtual void test_case_start(const TestCaseData&) = 0;
    // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input)
    virtual void test_case_reenter(const TestCaseData&) = 0;
    // called when a test case has ended
    virtual void test_case_end(const CurrentTestCaseStats&) = 0;

    // called when an exception is thrown from the test case (or it crashes)
    virtual void test_case_exception(const TestCaseException&) = 0;

    // called whenever a subcase is entered (don't cache pointers to the input)
    virtual void subcase_start(const SubcaseSignature&) = 0;
    // called whenever a subcase is exited (don't cache pointers to the input)
    virtual void subcase_end() = 0;

    // called for each assert (don't cache pointers to the input)
    virtual void log_assert(const AssertData&) = 0;
    // called for each message (don't cache pointers to the input)
    virtual void log_message(const MessageData&) = 0;

    // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator
    // or isn't in the execution range (between first and last) (safe to cache a pointer to the input)
    virtual void test_case_skipped(const TestCaseData&) = 0;

    // doctest will not be managing the lifetimes of reporters given to it but this would still be nice to have
    virtual ~IReporter();

    // can obtain all currently active contexts and stringify them if one wishes to do so
    static int                         get_num_active_contexts();
    static const IContextScope* const* get_active_contexts();

    // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown
    static int           get_num_stringified_contexts();
    static const String* get_stringified_contexts();
};

namespace detail {
    typedef IReporter* (*reporterCreatorFunc)(const ContextOptions&);

    DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter);

    template <typename Reporter>
    IReporter* reporterCreator(const ContextOptions& o) {
        return new Reporter(o);
    }
} // namespace detail

template <typename Reporter>
int registerReporter(const char* name, int priority, bool isReporter) {
    detail::registerReporterImpl(name, priority, detail::reporterCreator<Reporter>, isReporter);
    return 0;
}
} // namespace doctest

// if registering is not disabled
#if !defined(DOCTEST_CONFIG_DISABLE)

// common code in asserts - for convenience
#define DOCTEST_ASSERT_LOG_REACT_RETURN(b)                                                         \
    if(b.log())                                                                                    \
        DOCTEST_BREAK_INTO_DEBUGGER();                                                             \
    b.react(); \
    return !b.m_failed

#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#define DOCTEST_WRAP_IN_TRY(x) x;
#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS
#define DOCTEST_WRAP_IN_TRY(x)                                                                     \
    try {                                                                                          \
        x;                                                                                         \
    } catch(...) { DOCTEST_RB.translateException(); }
#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS

#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
#define DOCTEST_CAST_TO_VOID(...)                                                                  \
    DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast")                                       \
    static_cast<void>(__VA_ARGS__);                                                                \
    DOCTEST_GCC_SUPPRESS_WARNING_POP
#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS
#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__;
#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS

// registers the test by initializing a dummy var with a function
#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators)                                    \
    global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_),                 \
            doctest::detail::regTest(                                                              \
                    doctest::detail::TestCase(                                                     \
                            f, __FILE__, __LINE__,                                                 \
                            doctest_detail_test_suite_ns::getCurrentTestSuite()) *                 \
                    decorators))

#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators)                                     \
    namespace {                                                                                    \
        struct der : public base                                                                   \
        {                                                                                          \
            void f();                                                                              \
        };                                                                                         \
        static void func() {                                                                       \
            der v;                                                                                 \
            v.f();                                                                                 \
        }                                                                                          \
        DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators)                                 \
    }                                                                                              \
    inline DOCTEST_NOINLINE void der::f()

#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators)                                        \
    static void f();                                                                               \
    DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators)                                        \
    static void f()

#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators)                        \
    static doctest::detail::funcType proxy() { return f; }                                         \
    DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators)                                   \
    static void f()

// for registering tests
#define DOCTEST_TEST_CASE(decorators)                                                              \
    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)

// for registering tests in classes - requires C++17 for inline variables!
#if __cplusplus >= 201703L || (DOCTEST_MSVC >= DOCTEST_COMPILER(19, 12, 0) && _MSVC_LANG >= 201703L)
#define DOCTEST_TEST_CASE_CLASS(decorators)                                                        \
    DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_),           \
                                                  DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_),          \
                                                  decorators)
#else // DOCTEST_TEST_CASE_CLASS
#define DOCTEST_TEST_CASE_CLASS(...)                                                               \
    TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER
#endif // DOCTEST_TEST_CASE_CLASS

// for registering tests with a fixture
#define DOCTEST_TEST_CASE_FIXTURE(c, decorators)                                                   \
    DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c,                           \
                              DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators)

// for converting types to strings without the <typeinfo> header and demangling
#define DOCTEST_TYPE_TO_STRING_IMPL(...)                                                           \
    template <>                                                                                    \
    inline const char* type_to_string<__VA_ARGS__>() {                                             \
        return "<" #__VA_ARGS__ ">";                                                               \
    }
#define DOCTEST_TYPE_TO_STRING(...)                                                                \
    namespace doctest { namespace detail {                                                         \
            DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__)                                               \
        }                                                                                          \
    }                                                                                              \
    static_assert(true, "")

#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func)                                 \
    template <typename T>                                                                          \
    static void func();                                                                            \
    namespace {                                                                                    \
        template <typename Tuple>                                                                  \
        struct iter;                                                                               \
        template <typename Type, typename... Rest>                                                 \
        struct iter<std::tuple<Type, Rest...>>                                                     \
        {                                                                                          \
            iter(const char* file, unsigned line, int index) {                                     \
                doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line,         \
                                            doctest_detail_test_suite_ns::getCurrentTestSuite(),   \
                                            doctest::detail::type_to_string<Type>(),               \
                                            int(line) * 1000 + index)                              \
                                         * dec);                                                   \
                iter<std::tuple<Rest...>>(file, line, index + 1);                                  \
            }                                                                                      \
        };                                                                                         \
        template <>                                                                                \
        struct iter<std::tuple<>>                                                                  \
        {                                                                                          \
            iter(const char*, unsigned, int) {}                                                    \
        };                                                                                         \
    }                                                                                              \
    template <typename T>                                                                          \
    static void func()

#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id)                                              \
    DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR),                      \
                                           DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_))

#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...)                                 \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY),                                           \
        doctest::detail::instantiationHelper(                                                      \
            DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0)))

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...)                                                 \
    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
    static_assert(true, "")

#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...)                                                  \
    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \
    static_assert(true, "")

#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...)                                         \
    DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon);             \
    DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>)               \
    template <typename T>                                                                          \
    static void anon()

#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...)                                                    \
    DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__)

// for subcases
#define DOCTEST_SUBCASE(name)                                                                      \
    if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED =  \
               doctest::detail::Subcase(name, __FILE__, __LINE__))

// for grouping tests in test suites by using code blocks
#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name)                                               \
    namespace ns_name { namespace doctest_detail_test_suite_ns {                                   \
            static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() {            \
                DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640)                                      \
                DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors")                \
                DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers")             \
                static doctest::detail::TestSuite data{};                                          \
                static bool                       inited = false;                                  \
                DOCTEST_MSVC_SUPPRESS_WARNING_POP                                                  \
                DOCTEST_CLANG_SUPPRESS_WARNING_POP                                                 \
                DOCTEST_GCC_SUPPRESS_WARNING_POP                                                   \
                if(!inited) {                                                                      \
                    data* decorators;                                                              \
                    inited = true;                                                                 \
                }                                                                                  \
                return data;                                                                       \
            }                                                                                      \
        }                                                                                          \
    }                                                                                              \
    namespace ns_name

#define DOCTEST_TEST_SUITE(decorators)                                                             \
    DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_))

// for starting a testsuite block
#define DOCTEST_TEST_SUITE_BEGIN(decorators)                                                       \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_),                               \
            doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators))              \
    static_assert(true, "")

// for ending a testsuite block
#define DOCTEST_TEST_SUITE_END                                                                     \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_),                               \
            doctest::detail::setTestSuite(doctest::detail::TestSuite() * ""))                      \
    typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)

// for registering exception translators
#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature)                      \
    inline doctest::String translatorName(signature);                                              \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_),                        \
            doctest::registerExceptionTranslator(translatorName))                                  \
    doctest::String translatorName(signature)

#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)                                           \
    DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_),        \
                                               signature)

// for registering reporters
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)                                        \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_),                          \
            doctest::registerReporter<reporter>(name, priority, true))                             \
    static_assert(true, "")

// for registering listeners
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)                                        \
    DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_),                          \
            doctest::registerReporter<reporter>(name, priority, false))                            \
    static_assert(true, "")

// clang-format off
// for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557
#define DOCTEST_INFO(...)                                                                          \
    DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_),                                         \
                      DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_),                                   \
                      __VA_ARGS__)
// clang-format on

#define DOCTEST_INFO_IMPL(mb_name, s_name, ...)                                       \
    auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(                  \
        [&](std::ostream* s_name) {                                                                \
        doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
        mb_name.m_stream = s_name;                                                                 \
        mb_name * __VA_ARGS__;                                                                     \
    })

#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)

#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...)                                             \
    [&] {                                                                                          \
        doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type);                 \
        mb * __VA_ARGS__;                                                                          \
        if(mb.log())                                                                               \
            DOCTEST_BREAK_INTO_DEBUGGER();                                                         \
        mb.react();                                                                                \
    }()

// clang-format off
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__)
// clang-format on

#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__)
#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__)

#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility.

#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS

#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...)                                               \
    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses")                  \
    doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,          \
                                               __LINE__, #__VA_ARGS__);                            \
    DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult(                                                      \
            doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type)                \
            << __VA_ARGS__))                                                                       \
    DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB)                                                    \
    DOCTEST_CLANG_SUPPRESS_WARNING_POP

#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...)                                               \
    [&] {                                                                                          \
        DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__);                                      \
    }()

#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS

// necessary for <ASSERT>_MESSAGE
#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1

#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...)                                               \
    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses")                  \
    doctest::detail::decomp_assert(                                                                \
            doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__,                    \
            doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type)                \
                    << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP

#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS

#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__)
#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__)
#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__)
#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__)
#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__)
#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__)

// clang-format off
#define DOCTEST_WARN_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); }()
#define DOCTEST_CHECK_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); }()
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); }()
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); }()
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); }()
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); }()
// clang-format on

#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...)                                  \
    [&] {                                                                                          \
        if(!doctest::getContextOptions()->no_throw) {                                              \
            doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,  \
                                                       __LINE__, #expr, #__VA_ARGS__, message);    \
            try {                                                                                  \
                DOCTEST_CAST_TO_VOID(expr)                                                         \
            } catch(const typename doctest::detail::remove_const<                                  \
                    typename doctest::detail::remove_reference<__VA_ARGS__>::type>::type&) {       \
                DOCTEST_RB.translateException();                                                   \
                DOCTEST_RB.m_threw_as = true;                                                      \
            } catch(...) { DOCTEST_RB.translateException(); }                                      \
            DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB);                                           \
        } else {                                                                                   \
            return false;                                                                          \
        }                                                                                          \
    }()

#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...)                               \
    [&] {                                                                                          \
        if(!doctest::getContextOptions()->no_throw) {                                              \
            doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,  \
                                                       __LINE__, expr_str, "", __VA_ARGS__);       \
            try {                                                                                  \
                DOCTEST_CAST_TO_VOID(expr)                                                         \
            } catch(...) { DOCTEST_RB.translateException(); }                                      \
            DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB);                                           \
        } else {                                                                                   \
           return false;                                                                           \
        }                                                                                          \
    }()

#define DOCTEST_ASSERT_NOTHROW(assert_type, ...)                                                   \
    [&] {                                                                                          \
        doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,      \
                                                   __LINE__, #__VA_ARGS__);                        \
        try {                                                                                      \
            DOCTEST_CAST_TO_VOID(__VA_ARGS__)                                                      \
        } catch(...) { DOCTEST_RB.translateException(); }                                          \
        DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB);                                               \
    }()

// clang-format off
#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "")
#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "")
#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "")

#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__)

#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__)

#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__)
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__)
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__)

#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__)
#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__)
#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__)

#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); }()
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); }()
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); }()
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); }()
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); }()
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); }()
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); }()
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); }()
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); }()
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); }()
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); }()
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); }()
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); }()
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); }()
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] {DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); }()
// clang-format on

#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS

#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...)                                              \
    [&] {                                                                                          \
        doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,      \
                                                   __LINE__, #__VA_ARGS__);                        \
        DOCTEST_WRAP_IN_TRY(                                                                       \
                DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(           \
                        __VA_ARGS__))                                                              \
        DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB);                                               \
    }()

#define DOCTEST_UNARY_ASSERT(assert_type, ...)                                                     \
    [&] {                                                                                          \
        doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__,      \
                                                   __LINE__, #__VA_ARGS__);                        \
        DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__))                                  \
        DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB);                                               \
    }()

#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS

#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...)                                        \
    doctest::detail::binary_assert<doctest::detail::binaryAssertComparison::comparison>(           \
            doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__)

#define DOCTEST_UNARY_ASSERT(assert_type, ...)                                                     \
    doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__,            \
                                  #__VA_ARGS__, __VA_ARGS__)

#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS

#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__)
#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__)
#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__)
#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__)
#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__)
#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__)
#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__)
#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__)
#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__)
#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__)
#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__)
#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__)
#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__)
#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__)
#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__)
#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__)
#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__)
#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__)

#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__)
#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__)
#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__)
#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__)
#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__)
#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__)

#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS

#undef DOCTEST_WARN_THROWS
#undef DOCTEST_CHECK_THROWS
#undef DOCTEST_REQUIRE_THROWS
#undef DOCTEST_WARN_THROWS_AS
#undef DOCTEST_CHECK_THROWS_AS
#undef DOCTEST_REQUIRE_THROWS_AS
#undef DOCTEST_WARN_THROWS_WITH
#undef DOCTEST_CHECK_THROWS_WITH
#undef DOCTEST_REQUIRE_THROWS_WITH
#undef DOCTEST_WARN_THROWS_WITH_AS
#undef DOCTEST_CHECK_THROWS_WITH_AS
#undef DOCTEST_REQUIRE_THROWS_WITH_AS
#undef DOCTEST_WARN_NOTHROW
#undef DOCTEST_CHECK_NOTHROW
#undef DOCTEST_REQUIRE_NOTHROW

#undef DOCTEST_WARN_THROWS_MESSAGE
#undef DOCTEST_CHECK_THROWS_MESSAGE
#undef DOCTEST_REQUIRE_THROWS_MESSAGE
#undef DOCTEST_WARN_THROWS_AS_MESSAGE
#undef DOCTEST_CHECK_THROWS_AS_MESSAGE
#undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE
#undef DOCTEST_WARN_THROWS_WITH_MESSAGE
#undef DOCTEST_CHECK_THROWS_WITH_MESSAGE
#undef DOCTEST_REQUIRE_THROWS_WITH_MESSAGE
#undef DOCTEST_WARN_THROWS_WITH_AS_MESSAGE
#undef DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE
#undef DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE
#undef DOCTEST_WARN_NOTHROW_MESSAGE
#undef DOCTEST_CHECK_NOTHROW_MESSAGE
#undef DOCTEST_REQUIRE_NOTHROW_MESSAGE

#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS

#define DOCTEST_WARN_THROWS(...) ([] { return false; })
#define DOCTEST_CHECK_THROWS(...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS(...) ([] { return false; })
#define DOCTEST_WARN_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_WARN_NOTHROW(...) ([] { return false; })
#define DOCTEST_CHECK_NOTHROW(...) ([] { return false; })
#define DOCTEST_REQUIRE_NOTHROW(...) ([] { return false; })

#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) ([] { return false; })

#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS

#undef DOCTEST_REQUIRE
#undef DOCTEST_REQUIRE_FALSE
#undef DOCTEST_REQUIRE_MESSAGE
#undef DOCTEST_REQUIRE_FALSE_MESSAGE
#undef DOCTEST_REQUIRE_EQ
#undef DOCTEST_REQUIRE_NE
#undef DOCTEST_REQUIRE_GT
#undef DOCTEST_REQUIRE_LT
#undef DOCTEST_REQUIRE_GE
#undef DOCTEST_REQUIRE_LE
#undef DOCTEST_REQUIRE_UNARY
#undef DOCTEST_REQUIRE_UNARY_FALSE

#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS

#endif // DOCTEST_CONFIG_NO_EXCEPTIONS

// =================================================================================================
// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING!                      ==
// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY!                            ==
// =================================================================================================
#else // DOCTEST_CONFIG_DISABLE

#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name)                                           \
    namespace {                                                                                    \
        template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                           \
        struct der : public base                                                                   \
        { void f(); };                                                                             \
    }                                                                                              \
    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \
    inline void der<DOCTEST_UNUSED_TEMPLATE_TYPE>::f()

#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name)                                              \
    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \
    static inline void f()

// for registering tests
#define DOCTEST_TEST_CASE(name)                                                                    \
    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)

// for registering tests in classes
#define DOCTEST_TEST_CASE_CLASS(name)                                                              \
    DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)

// for registering tests with a fixture
#define DOCTEST_TEST_CASE_FIXTURE(x, name)                                                         \
    DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x,                           \
                              DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name)

// for converting types to strings without the <typeinfo> header and demangling
#define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "")
#define DOCTEST_TYPE_TO_STRING_IMPL(...)

// for typed tests
#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...)                                                \
    template <typename type>                                                                       \
    inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()

#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id)                                          \
    template <typename type>                                                                       \
    inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)()

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "")
#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "")

// for subcases
#define DOCTEST_SUBCASE(name)

// for a testsuite block
#define DOCTEST_TEST_SUITE(name) namespace

// for starting a testsuite block
#define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "")

// for ending a testsuite block
#define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_)

#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)                                           \
    template <typename DOCTEST_UNUSED_TEMPLATE_TYPE>                                               \
    static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature)

#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)

#define DOCTEST_INFO(...) (static_cast<void>(0))
#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast<void>(0))
#define DOCTEST_MESSAGE(...) (static_cast<void>(0))
#define DOCTEST_FAIL_CHECK(...) (static_cast<void>(0))
#define DOCTEST_FAIL(...) (static_cast<void>(0))

#ifdef DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED

#define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }()
#define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }()

#define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }()
#define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }()
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }()
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }()

namespace doctest {
namespace detail {
#define DOCTEST_RELATIONAL_OP(name, op)                                                            \
    template <typename L, typename R>                                                              \
    bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; }

    DOCTEST_RELATIONAL_OP(eq, ==)
    DOCTEST_RELATIONAL_OP(ne, !=)
    DOCTEST_RELATIONAL_OP(lt, <)
    DOCTEST_RELATIONAL_OP(gt, >)
    DOCTEST_RELATIONAL_OP(le, <=)
    DOCTEST_RELATIONAL_OP(ge, >=)
} // namespace detail
} // namespace doctest

#define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
#define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }()
#define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
#define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }()
#define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
#define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }()
#define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
#define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }()
#define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
#define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }()
#define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
#define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }()
#define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }()
#define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
#define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()
#define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }()

#else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED

#define DOCTEST_WARN(...) ([] { return false; })
#define DOCTEST_CHECK(...) ([] { return false; })
#define DOCTEST_REQUIRE(...) ([] { return false; })
#define DOCTEST_WARN_FALSE(...) ([] { return false; })
#define DOCTEST_CHECK_FALSE(...) ([] { return false; })
#define DOCTEST_REQUIRE_FALSE(...) ([] { return false; })

#define DOCTEST_WARN_MESSAGE(cond, ...) ([] { return false; })
#define DOCTEST_CHECK_MESSAGE(cond, ...) ([] { return false; })
#define DOCTEST_REQUIRE_MESSAGE(cond, ...) ([] { return false; })
#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) ([] { return false; })
#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) ([] { return false; })
#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) ([] { return false; })

#define DOCTEST_WARN_EQ(...) ([] { return false; })
#define DOCTEST_CHECK_EQ(...) ([] { return false; })
#define DOCTEST_REQUIRE_EQ(...) ([] { return false; })
#define DOCTEST_WARN_NE(...) ([] { return false; })
#define DOCTEST_CHECK_NE(...) ([] { return false; })
#define DOCTEST_REQUIRE_NE(...) ([] { return false; })
#define DOCTEST_WARN_GT(...) ([] { return false; })
#define DOCTEST_CHECK_GT(...) ([] { return false; })
#define DOCTEST_REQUIRE_GT(...) ([] { return false; })
#define DOCTEST_WARN_LT(...) ([] { return false; })
#define DOCTEST_CHECK_LT(...) ([] { return false; })
#define DOCTEST_REQUIRE_LT(...) ([] { return false; })
#define DOCTEST_WARN_GE(...) ([] { return false; })
#define DOCTEST_CHECK_GE(...) ([] { return false; })
#define DOCTEST_REQUIRE_GE(...) ([] { return false; })
#define DOCTEST_WARN_LE(...) ([] { return false; })
#define DOCTEST_CHECK_LE(...) ([] { return false; })
#define DOCTEST_REQUIRE_LE(...) ([] { return false; })

#define DOCTEST_WARN_UNARY(...) ([] { return false; })
#define DOCTEST_CHECK_UNARY(...) ([] { return false; })
#define DOCTEST_REQUIRE_UNARY(...) ([] { return false; })
#define DOCTEST_WARN_UNARY_FALSE(...) ([] { return false; })
#define DOCTEST_CHECK_UNARY_FALSE(...) ([] { return false; })
#define DOCTEST_REQUIRE_UNARY_FALSE(...) ([] { return false; })

#endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED

// TODO: think about if these also need to work properly even when doctest is disabled
#define DOCTEST_WARN_THROWS(...) ([] { return false; })
#define DOCTEST_CHECK_THROWS(...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS(...) ([] { return false; })
#define DOCTEST_WARN_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ([] { return false; })
#define DOCTEST_WARN_NOTHROW(...) ([] { return false; })
#define DOCTEST_CHECK_NOTHROW(...) ([] { return false; })
#define DOCTEST_REQUIRE_NOTHROW(...) ([] { return false; })

#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) ([] { return false; })
#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) ([] { return false; })
#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) ([] { return false; })
#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) ([] { return false; })

#endif // DOCTEST_CONFIG_DISABLE

// clang-format off
// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS
#define DOCTEST_FAST_WARN_EQ             DOCTEST_WARN_EQ
#define DOCTEST_FAST_CHECK_EQ            DOCTEST_CHECK_EQ
#define DOCTEST_FAST_REQUIRE_EQ          DOCTEST_REQUIRE_EQ
#define DOCTEST_FAST_WARN_NE             DOCTEST_WARN_NE
#define DOCTEST_FAST_CHECK_NE            DOCTEST_CHECK_NE
#define DOCTEST_FAST_REQUIRE_NE          DOCTEST_REQUIRE_NE
#define DOCTEST_FAST_WARN_GT             DOCTEST_WARN_GT
#define DOCTEST_FAST_CHECK_GT            DOCTEST_CHECK_GT
#define DOCTEST_FAST_REQUIRE_GT          DOCTEST_REQUIRE_GT
#define DOCTEST_FAST_WARN_LT             DOCTEST_WARN_LT
#define DOCTEST_FAST_CHECK_LT            DOCTEST_CHECK_LT
#define DOCTEST_FAST_REQUIRE_LT          DOCTEST_REQUIRE_LT
#define DOCTEST_FAST_WARN_GE             DOCTEST_WARN_GE
#define DOCTEST_FAST_CHECK_GE            DOCTEST_CHECK_GE
#define DOCTEST_FAST_REQUIRE_GE          DOCTEST_REQUIRE_GE
#define DOCTEST_FAST_WARN_LE             DOCTEST_WARN_LE
#define DOCTEST_FAST_CHECK_LE            DOCTEST_CHECK_LE
#define DOCTEST_FAST_REQUIRE_LE          DOCTEST_REQUIRE_LE

#define DOCTEST_FAST_WARN_UNARY          DOCTEST_WARN_UNARY
#define DOCTEST_FAST_CHECK_UNARY         DOCTEST_CHECK_UNARY
#define DOCTEST_FAST_REQUIRE_UNARY       DOCTEST_REQUIRE_UNARY
#define DOCTEST_FAST_WARN_UNARY_FALSE    DOCTEST_WARN_UNARY_FALSE
#define DOCTEST_FAST_CHECK_UNARY_FALSE   DOCTEST_CHECK_UNARY_FALSE
#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE

#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
// clang-format on

// BDD style macros
// clang-format off
#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE("  Scenario: " name)
#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS("  Scenario: " name)
#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...)  DOCTEST_TEST_CASE_TEMPLATE("  Scenario: " name, T, __VA_ARGS__)
#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE("  Scenario: " name, T, id)

#define DOCTEST_GIVEN(name)     DOCTEST_SUBCASE("   Given: " name)
#define DOCTEST_WHEN(name)      DOCTEST_SUBCASE("    When: " name)
#define DOCTEST_AND_WHEN(name)  DOCTEST_SUBCASE("And when: " name)
#define DOCTEST_THEN(name)      DOCTEST_SUBCASE("    Then: " name)
#define DOCTEST_AND_THEN(name)  DOCTEST_SUBCASE("     And: " name)
// clang-format on

// == SHORT VERSIONS OF THE MACROS
#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)

#define TEST_CASE(name) DOCTEST_TEST_CASE(name)
#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name)
#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
#define SUBCASE(name) DOCTEST_SUBCASE(name)
#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators)
#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name)
#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
#define INFO(...) DOCTEST_INFO(__VA_ARGS__)
#define CAPTURE(x) DOCTEST_CAPTURE(x)
#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__)
#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__)
#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__)

#define WARN(...) DOCTEST_WARN(__VA_ARGS__)
#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__)
#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__)
#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)

#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)

#define SCENARIO(name) DOCTEST_SCENARIO(name)
#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name)
#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
#define GIVEN(name) DOCTEST_GIVEN(name)
#define WHEN(name) DOCTEST_WHEN(name)
#define AND_WHEN(name) DOCTEST_AND_WHEN(name)
#define THEN(name) DOCTEST_THEN(name)
#define AND_THEN(name) DOCTEST_AND_THEN(name)

#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__)
#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__)
#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__)
#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__)
#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__)
#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__)
#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__)
#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__)
#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__)
#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__)
#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__)
#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)

// KEPT FOR BACKWARDS COMPATIBILITY
#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)

#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)

#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)

#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES

#if !defined(DOCTEST_CONFIG_DISABLE)

// this is here to clear the 'current test suite' for the current translation unit - at the top
DOCTEST_TEST_SUITE_END();

// add stringification for primitive/fundamental types
namespace doctest { namespace detail {
    DOCTEST_TYPE_TO_STRING_IMPL(bool)
    DOCTEST_TYPE_TO_STRING_IMPL(float)
    DOCTEST_TYPE_TO_STRING_IMPL(double)
    DOCTEST_TYPE_TO_STRING_IMPL(long double)
    DOCTEST_TYPE_TO_STRING_IMPL(char)
    DOCTEST_TYPE_TO_STRING_IMPL(signed char)
    DOCTEST_TYPE_TO_STRING_IMPL(unsigned char)
#if !DOCTEST_MSVC || defined(_NATIVE_WCHAR_T_DEFINED)
    DOCTEST_TYPE_TO_STRING_IMPL(wchar_t)
#endif // not MSVC or wchar_t support enabled
    DOCTEST_TYPE_TO_STRING_IMPL(short int)
    DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int)
    DOCTEST_TYPE_TO_STRING_IMPL(int)
    DOCTEST_TYPE_TO_STRING_IMPL(unsigned int)
    DOCTEST_TYPE_TO_STRING_IMPL(long int)
    DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int)
    DOCTEST_TYPE_TO_STRING_IMPL(long long int)
    DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int)
}} // namespace doctest::detail

#endif // DOCTEST_CONFIG_DISABLE

DOCTEST_CLANG_SUPPRESS_WARNING_POP
DOCTEST_MSVC_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP

DOCTEST_SUPPRESS_COMMON_WARNINGS_POP

#endif // DOCTEST_LIBRARY_INCLUDED

#ifndef DOCTEST_SINGLE_HEADER
#define DOCTEST_SINGLE_HEADER
#endif // DOCTEST_SINGLE_HEADER

#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER)

#ifndef DOCTEST_SINGLE_HEADER
#include "doctest_fwd.h"
#endif // DOCTEST_SINGLE_HEADER

DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros")

#ifndef DOCTEST_LIBRARY_IMPLEMENTATION
#define DOCTEST_LIBRARY_IMPLEMENTATION

DOCTEST_CLANG_SUPPRESS_WARNING_POP

DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH

DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function")
DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path")

DOCTEST_GCC_SUPPRESS_WARNING_PUSH
DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion")
DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion")
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers")
DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces")
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch")
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum")
DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default")
DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations")
DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast")
DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function")
DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance")
DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute")

DOCTEST_MSVC_SUPPRESS_WARNING_PUSH
DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data
DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled
DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified
DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal
DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch
DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C
DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning)
DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal linkage has been removed

DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN

// required includes - will go only in one translation unit!
#include <ctime>
#include <cmath>
#include <climits>
// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/doctest/doctest/pull/37
#ifdef __BORLANDC__
#include <math.h>
#endif // __BORLANDC__
#include <new>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <utility>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <atomic>
#include <mutex>
#include <set>
#include <map>
#include <exception>
#include <stdexcept>
#include <csignal>
#include <cfloat>
#include <cctype>
#include <cstdint>

#ifdef DOCTEST_PLATFORM_MAC
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
#endif // DOCTEST_PLATFORM_MAC

#ifdef DOCTEST_PLATFORM_WINDOWS

// defines for a leaner windows.h
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#ifndef NOMINMAX
#define NOMINMAX
#endif // NOMINMAX

// not sure what AfxWin.h is for - here I do what Catch does
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#include <windows.h>
#endif
#include <io.h>

#else // DOCTEST_PLATFORM_WINDOWS

#include <sys/time.h>
#include <unistd.h>

#endif // DOCTEST_PLATFORM_WINDOWS

// this is a fix for https://github.com/doctest/doctest/issues/348
// https://mail.gnome.org/archives/xml/2012-January/msg00000.html
#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO)
#define STDOUT_FILENO fileno(stdout)
#endif // HAVE_UNISTD_H

DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END

// counts the number of elements in a C array
#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0]))

#ifdef DOCTEST_CONFIG_DISABLE
#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled
#else // DOCTEST_CONFIG_DISABLE
#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled
#endif // DOCTEST_CONFIG_DISABLE

#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX
#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-"
#endif

#ifndef DOCTEST_THREAD_LOCAL
#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0))
#define DOCTEST_THREAD_LOCAL
#else // DOCTEST_MSVC
#define DOCTEST_THREAD_LOCAL thread_local
#endif // DOCTEST_MSVC
#endif // DOCTEST_THREAD_LOCAL

#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
#endif

#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
#endif

#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
#else
#define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
#endif

#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
#endif

#ifndef DOCTEST_CDECL
#define DOCTEST_CDECL __cdecl
#endif

namespace doctest {

bool is_running_in_test = false;

namespace {
    using namespace detail;

    template <typename Ex>
    DOCTEST_NORETURN void throw_exception(Ex const& e) {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
        throw e;
#else  // DOCTEST_CONFIG_NO_EXCEPTIONS
        std::cerr << "doctest will terminate because it needed to throw an exception.\n"
                  << "The message was: " << e.what() << '\n';
        std::terminate();
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
    }

#ifndef DOCTEST_INTERNAL_ERROR
#define DOCTEST_INTERNAL_ERROR(msg)                                                                \
    throw_exception(std::logic_error(                                                              \
            __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg))
#endif // DOCTEST_INTERNAL_ERROR

    // case insensitive strcmp
    int stricmp(const char* a, const char* b) {
        for(;; a++, b++) {
            const int d = tolower(*a) - tolower(*b);
            if(d != 0 || !*a)
                return d;
        }
    }

    template <typename T>
    String fpToString(T value, int precision) {
        std::ostringstream oss;
        oss << std::setprecision(precision) << std::fixed << value;
        std::string d = oss.str();
        size_t      i = d.find_last_not_of('0');
        if(i != std::string::npos && i != d.size() - 1) {
            if(d[i] == '.')
                i++;
            d = d.substr(0, i + 1);
        }
        return d.c_str();
    }

    struct Endianness
    {
        enum Arch
        {
            Big,
            Little
        };

        static Arch which() {
            int x = 1;
            // casting any data pointer to char* is allowed
            auto ptr = reinterpret_cast<char*>(&x);
            if(*ptr)
                return Little;
            return Big;
        }
    };
} // namespace

namespace detail {
    String rawMemoryToString(const void* object, unsigned size) {
        // Reverse order for little endian architectures
        int i = 0, end = static_cast<int>(size), inc = 1;
        if(Endianness::which() == Endianness::Little) {
            i   = end - 1;
            end = inc = -1;
        }

        unsigned const char* bytes = static_cast<unsigned const char*>(object);
        std::ostream*        oss   = tlssPush();
        *oss << "0x" << std::setfill('0') << std::hex;
        for(; i != end; i += inc)
            *oss << std::setw(2) << static_cast<unsigned>(bytes[i]);
        return tlssPop();
    }

    DOCTEST_THREAD_LOCAL class
    {
        std::vector<std::streampos> stack;
        std::stringstream           ss;

    public:
        std::ostream* push() {
            stack.push_back(ss.tellp());
            return &ss;
        }

        String pop() {
            if (stack.empty())
                DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!");

            std::streampos pos = stack.back();
            stack.pop_back();
            unsigned sz = static_cast<unsigned>(ss.tellp() - pos);
            ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out);
            return String(ss, sz);
        }
    } g_oss;

    std::ostream* tlssPush() {
        return g_oss.push();
    }

    String tlssPop() {
        return g_oss.pop();
    }

#ifndef DOCTEST_CONFIG_DISABLE

namespace timer_large_integer
{
    
#if defined(DOCTEST_PLATFORM_WINDOWS)
    typedef ULONGLONG type;
#else // DOCTEST_PLATFORM_WINDOWS
    typedef std::uint64_t type;
#endif // DOCTEST_PLATFORM_WINDOWS
}

typedef timer_large_integer::type ticks_t;

#ifdef DOCTEST_CONFIG_GETCURRENTTICKS
    ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
#elif defined(DOCTEST_PLATFORM_WINDOWS)
    ticks_t getCurrentTicks() {
        static LARGE_INTEGER hz = {0}, hzo = {0};
        if(!hz.QuadPart) {
            QueryPerformanceFrequency(&hz);
            QueryPerformanceCounter(&hzo);
        }
        LARGE_INTEGER t;
        QueryPerformanceCounter(&t);
        return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart;
    }
#else  // DOCTEST_PLATFORM_WINDOWS
    ticks_t getCurrentTicks() {
        timeval t;
        gettimeofday(&t, nullptr);
        return static_cast<ticks_t>(t.tv_sec) * 1000000 + static_cast<ticks_t>(t.tv_usec);
    }
#endif // DOCTEST_PLATFORM_WINDOWS

    struct Timer
    {
        void         start() { m_ticks = getCurrentTicks(); }
        unsigned int getElapsedMicroseconds() const {
            return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
        }
        //unsigned int getElapsedMilliseconds() const {
        //    return static_cast<unsigned int>(getElapsedMicroseconds() / 1000);
        //}
        double getElapsedSeconds() const { return static_cast<double>(getCurrentTicks() - m_ticks) / 1000000.0; }

    private:
        ticks_t m_ticks = 0;
    };

#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
    template <typename T>
    using AtomicOrMultiLaneAtomic = std::atomic<T>;
#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
    // Provides a multilane implementation of an atomic variable that supports add, sub, load,
    // store. Instead of using a single atomic variable, this splits up into multiple ones,
    // each sitting on a separate cache line. The goal is to provide a speedup when most
    // operations are modifying. It achieves this with two properties:
    //
    // * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
    // * Each atomic sits on a separate cache line, so false sharing is reduced.
    //
    // The disadvantage is that there is a small overhead due to the use of TLS, and load/store
    // is slower because all atomics have to be accessed.
    template <typename T>
    class MultiLaneAtomic
    {
        struct CacheLineAlignedAtomic
        {
            std::atomic<T> atomic{};
            char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(std::atomic<T>)];
        };
        CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES];

        static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE,
                      "guarantee one atomic takes exactly one cache line");

    public:
        T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; }

        T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); }

        T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
            return myAtomic().fetch_add(arg, order);
        }

        T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
            return myAtomic().fetch_sub(arg, order);
        }

        operator T() const DOCTEST_NOEXCEPT { return load(); }

        T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT {
            auto result = T();
            for(auto const& c : m_atomics) {
                result += c.atomic.load(order);
            }
            return result;
        }

        T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm [cpp/assignment-does-not-return-this]
            store(desired);
            return desired;
        }

        void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT {
            // first value becomes desired", all others become 0.
            for(auto& c : m_atomics) {
                c.atomic.store(desired, order);
                desired = {};
            }
        }

    private:
        // Each thread has a different atomic that it operates on. If more than NumLanes threads
        // use this, some will use the same atomic. So performance will degrade a bit, but still
        // everything will work.
        //
        // The logic here is a bit tricky. The call should be as fast as possible, so that there
        // is minimal to no overhead in determining the correct atomic for the current thread.
        //
        // 1. A global static counter laneCounter counts continuously up.
        // 2. Each successive thread will use modulo operation of that counter so it gets an atomic
        //    assigned in a round-robin fashion.
        // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
        //    little overhead.
        std::atomic<T>& myAtomic() DOCTEST_NOEXCEPT {
            static std::atomic<size_t> laneCounter;
            DOCTEST_THREAD_LOCAL size_t tlsLaneIdx =
                    laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES;

            return m_atomics[tlsLaneIdx].atomic;
        }
    };

    template <typename T>
    using AtomicOrMultiLaneAtomic = MultiLaneAtomic<T>;
#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS

    // this holds both parameters from the command line and runtime data for tests
    struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats
    {
        AtomicOrMultiLaneAtomic<int> numAssertsCurrentTest_atomic;
        AtomicOrMultiLaneAtomic<int> numAssertsFailedCurrentTest_atomic;

        std::vector<std::vector<String>> filters = decltype(filters)(9); // 9 different filters

        std::vector<IReporter*> reporters_currently_used;

        assert_handler ah = nullptr;

        Timer timer;

        std::vector<String> stringifiedContexts; // logging from INFO() due to an exception

        // stuff for subcases
        std::vector<SubcaseSignature>     subcasesStack;
        std::set<decltype(subcasesStack)> subcasesPassed;
        int                               subcasesCurrentMaxLevel;
        bool                              should_reenter;
        std::atomic<bool>                 shouldLogCurrentException;

        void resetRunData() {
            numTestCases                = 0;
            numTestCasesPassingFilters  = 0;
            numTestSuitesPassingFilters = 0;
            numTestCasesFailed          = 0;
            numAsserts                  = 0;
            numAssertsFailed            = 0;
            numAssertsCurrentTest       = 0;
            numAssertsFailedCurrentTest = 0;
        }

        void finalizeTestCaseData() {
            seconds = timer.getElapsedSeconds();

            // update the non-atomic counters
            numAsserts += numAssertsCurrentTest_atomic;
            numAssertsFailed += numAssertsFailedCurrentTest_atomic;
            numAssertsCurrentTest       = numAssertsCurrentTest_atomic;
            numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic;

            if(numAssertsFailedCurrentTest)
                failure_flags |= TestCaseFailureReason::AssertFailure;

            if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 &&
               Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout)
                failure_flags |= TestCaseFailureReason::Timeout;

            if(currentTest->m_should_fail) {
                if(failure_flags) {
                    failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid;
                } else {
                    failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt;
                }
            } else if(failure_flags && currentTest->m_may_fail) {
                failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid;
            } else if(currentTest->m_expected_failures > 0) {
                if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) {
                    failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes;
                } else {
                    failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes;
                }
            }

            bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) ||
                              (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) ||
                              (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags);

            // if any subcase has failed - the whole test case has failed
            testCaseSuccess = !(failure_flags && !ok_to_fail);
            if(!testCaseSuccess)
                numTestCasesFailed++;
        }
    };

    ContextState* g_cs = nullptr;

    // used to avoid locks for the debug output
    // TODO: figure out if this is indeed necessary/correct - seems like either there still
    // could be a race or that there wouldn't be a race even if using the context directly
    DOCTEST_THREAD_LOCAL bool g_no_colors;

#endif // DOCTEST_CONFIG_DISABLE
} // namespace detail

char* String::allocate(unsigned sz) {
    if (sz <= last) {
        buf[sz] = '\0';
        setLast(last - sz);
        return buf;
    } else {
        setOnHeap();
        data.size = sz;
        data.capacity = data.size + 1;
        data.ptr = new char[data.capacity];
        data.ptr[sz] = '\0';
        return data.ptr;
    }
}

void String::setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; }
void String::setLast(unsigned in) { buf[last] = char(in); }

void String::copy(const String& other) {
    if(other.isOnStack()) {
        memcpy(buf, other.buf, len);
    } else {
        memcpy(allocate(other.data.size), other.data.ptr, other.data.size);
    }
}

String::String() {
    buf[0] = '\0';
    setLast();
}

String::~String() {
    if(!isOnStack())
        delete[] data.ptr;
    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
}

String::String(const char* in)
        : String(in, strlen(in)) {}

String::String(const char* in, unsigned in_size) {
    memcpy(allocate(in_size), in, in_size);
}

String::String(std::istream& in, unsigned in_size) {
    in.read(allocate(in_size), in_size);
}

String::String(const String& other) { copy(other); }

String& String::operator=(const String& other) {
    if(this != &other) {
        if(!isOnStack())
            delete[] data.ptr;

        copy(other);
    }

    return *this;
}

String& String::operator+=(const String& other) {
    const unsigned my_old_size = size();
    const unsigned other_size  = other.size();
    const unsigned total_size  = my_old_size + other_size;
    if(isOnStack()) {
        if(total_size < len) {
            // append to the current stack space
            memcpy(buf + my_old_size, other.c_str(), other_size + 1);
            // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
            setLast(last - total_size);
        } else {
            // alloc new chunk
            char* temp = new char[total_size + 1];
            // copy current data to new location before writing in the union
            memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed
            // update data in union
            setOnHeap();
            data.size     = total_size;
            data.capacity = data.size + 1;
            data.ptr      = temp;
            // transfer the rest of the data
            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
        }
    } else {
        if(data.capacity > total_size) {
            // append to the current heap block
            data.size = total_size;
            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
        } else {
            // resize
            data.capacity *= 2;
            if(data.capacity <= total_size)
                data.capacity = total_size + 1;
            // alloc new chunk
            char* temp = new char[data.capacity];
            // copy current data to new location before releasing it
            memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed
            // release old chunk
            delete[] data.ptr;
            // update the rest of the union members
            data.size = total_size;
            data.ptr  = temp;
            // transfer the rest of the data
            memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1);
        }
    }

    return *this;
}

String::String(String&& other) {
    memcpy(buf, other.buf, len);
    other.buf[0] = '\0';
    other.setLast();
}

String& String::operator=(String&& other) {
    if(this != &other) {
        if(!isOnStack())
            delete[] data.ptr;
        memcpy(buf, other.buf, len);
        other.buf[0] = '\0';
        other.setLast();
    }
    return *this;
}

char String::operator[](unsigned i) const {
    return const_cast<String*>(this)->operator[](i); // NOLINT
}

char& String::operator[](unsigned i) {
    if(isOnStack())
        return reinterpret_cast<char*>(buf)[i];
    return data.ptr[i];
}

DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized")
unsigned String::size() const {
    if(isOnStack())
        return last - (unsigned(buf[last]) & 31); // using "last" would work only if "len" is 32
    return data.size;
}
DOCTEST_GCC_SUPPRESS_WARNING_POP

unsigned String::capacity() const {
    if(isOnStack())
        return len;
    return data.capacity;
}

int String::compare(const char* other, bool no_case) const {
    if(no_case)
        return doctest::stricmp(c_str(), other);
    return std::strcmp(c_str(), other);
}

int String::compare(const String& other, bool no_case) const {
    return compare(other.c_str(), no_case);
}

// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String operator+(const String& lhs, const String& rhs) { return  String(lhs) += rhs; }

// clang-format off
bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; }
bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; }
bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; }
bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; }
bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; }
// clang-format on

std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); }

namespace {
    void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;)
} // namespace

namespace Color {
    std::ostream& operator<<(std::ostream& s, Color::Enum code) {
        color_to_stream(s, code);
        return s;
    }
} // namespace Color

// clang-format off
const char* assertString(assertType::Enum at) {
    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4062) // enum 'x' in switch of enum 'y' is not handled
    switch(at) {  //!OCLINT missing default in switch statements
        case assertType::DT_WARN                    : return "WARN";
        case assertType::DT_CHECK                   : return "CHECK";
        case assertType::DT_REQUIRE                 : return "REQUIRE";

        case assertType::DT_WARN_FALSE              : return "WARN_FALSE";
        case assertType::DT_CHECK_FALSE             : return "CHECK_FALSE";
        case assertType::DT_REQUIRE_FALSE           : return "REQUIRE_FALSE";

        case assertType::DT_WARN_THROWS             : return "WARN_THROWS";
        case assertType::DT_CHECK_THROWS            : return "CHECK_THROWS";
        case assertType::DT_REQUIRE_THROWS          : return "REQUIRE_THROWS";

        case assertType::DT_WARN_THROWS_AS          : return "WARN_THROWS_AS";
        case assertType::DT_CHECK_THROWS_AS         : return "CHECK_THROWS_AS";
        case assertType::DT_REQUIRE_THROWS_AS       : return "REQUIRE_THROWS_AS";

        case assertType::DT_WARN_THROWS_WITH        : return "WARN_THROWS_WITH";
        case assertType::DT_CHECK_THROWS_WITH       : return "CHECK_THROWS_WITH";
        case assertType::DT_REQUIRE_THROWS_WITH     : return "REQUIRE_THROWS_WITH";

        case assertType::DT_WARN_THROWS_WITH_AS     : return "WARN_THROWS_WITH_AS";
        case assertType::DT_CHECK_THROWS_WITH_AS    : return "CHECK_THROWS_WITH_AS";
        case assertType::DT_REQUIRE_THROWS_WITH_AS  : return "REQUIRE_THROWS_WITH_AS";

        case assertType::DT_WARN_NOTHROW            : return "WARN_NOTHROW";
        case assertType::DT_CHECK_NOTHROW           : return "CHECK_NOTHROW";
        case assertType::DT_REQUIRE_NOTHROW         : return "REQUIRE_NOTHROW";

        case assertType::DT_WARN_EQ                 : return "WARN_EQ";
        case assertType::DT_CHECK_EQ                : return "CHECK_EQ";
        case assertType::DT_REQUIRE_EQ              : return "REQUIRE_EQ";
        case assertType::DT_WARN_NE                 : return "WARN_NE";
        case assertType::DT_CHECK_NE                : return "CHECK_NE";
        case assertType::DT_REQUIRE_NE              : return "REQUIRE_NE";
        case assertType::DT_WARN_GT                 : return "WARN_GT";
        case assertType::DT_CHECK_GT                : return "CHECK_GT";
        case assertType::DT_REQUIRE_GT              : return "REQUIRE_GT";
        case assertType::DT_WARN_LT                 : return "WARN_LT";
        case assertType::DT_CHECK_LT                : return "CHECK_LT";
        case assertType::DT_REQUIRE_LT              : return "REQUIRE_LT";
        case assertType::DT_WARN_GE                 : return "WARN_GE";
        case assertType::DT_CHECK_GE                : return "CHECK_GE";
        case assertType::DT_REQUIRE_GE              : return "REQUIRE_GE";
        case assertType::DT_WARN_LE                 : return "WARN_LE";
        case assertType::DT_CHECK_LE                : return "CHECK_LE";
        case assertType::DT_REQUIRE_LE              : return "REQUIRE_LE";

        case assertType::DT_WARN_UNARY              : return "WARN_UNARY";
        case assertType::DT_CHECK_UNARY             : return "CHECK_UNARY";
        case assertType::DT_REQUIRE_UNARY           : return "REQUIRE_UNARY";
        case assertType::DT_WARN_UNARY_FALSE        : return "WARN_UNARY_FALSE";
        case assertType::DT_CHECK_UNARY_FALSE       : return "CHECK_UNARY_FALSE";
        case assertType::DT_REQUIRE_UNARY_FALSE     : return "REQUIRE_UNARY_FALSE";
    }
    DOCTEST_MSVC_SUPPRESS_WARNING_POP
    return "";
}
// clang-format on

const char* failureString(assertType::Enum at) {
    if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional
        return "WARNING";
    if(at & assertType::is_check) //!OCLINT bitwise operator in conditional
        return "ERROR";
    if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
        return "FATAL ERROR";
    return "";
}

DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference")
// depending on the current options this will remove the path of filenames
const char* skipPathFromFilename(const char* file) {
#ifndef DOCTEST_CONFIG_DISABLE
    if(getContextOptions()->no_path_in_filenames) {
        auto back    = std::strrchr(file, '\\');
        auto forward = std::strrchr(file, '/');
        if(back || forward) {
            if(back > forward)
                forward = back;
            return forward + 1;
        }
    }
#endif // DOCTEST_CONFIG_DISABLE
    return file;
}
DOCTEST_CLANG_SUPPRESS_WARNING_POP
DOCTEST_GCC_SUPPRESS_WARNING_POP

bool SubcaseSignature::operator<(const SubcaseSignature& other) const {
    if(m_line != other.m_line)
        return m_line < other.m_line;
    if(std::strcmp(m_file, other.m_file) != 0)
        return std::strcmp(m_file, other.m_file) < 0;
    return m_name.compare(other.m_name) < 0;
}

IContextScope::IContextScope()  = default;
IContextScope::~IContextScope() = default;

#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(char* in) { return toString(static_cast<const char*>(in)); }
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; }
#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
String toString(bool in) { return in ? "true" : "false"; }
String toString(float in) { return fpToString(in, 5) + "f"; }
String toString(double in) { return fpToString(in, 10); }
String toString(double long in) { return fpToString(in, 15); }

#define DOCTEST_TO_STRING_OVERLOAD(type, fmt)                                                      \
    String toString(type in) {                                                                     \
        char buf[64];                                                                              \
        std::sprintf(buf, fmt, in);                                                                \
        return buf;                                                                                \
    }

DOCTEST_TO_STRING_OVERLOAD(char, "%d")
DOCTEST_TO_STRING_OVERLOAD(char signed, "%d")
DOCTEST_TO_STRING_OVERLOAD(char unsigned, "%u")
DOCTEST_TO_STRING_OVERLOAD(int short, "%d")
DOCTEST_TO_STRING_OVERLOAD(int short unsigned, "%u")
DOCTEST_TO_STRING_OVERLOAD(int, "%d")
DOCTEST_TO_STRING_OVERLOAD(unsigned, "%u")
DOCTEST_TO_STRING_OVERLOAD(int long, "%ld")
DOCTEST_TO_STRING_OVERLOAD(int long unsigned, "%lu")
DOCTEST_TO_STRING_OVERLOAD(int long long, "%lld")
DOCTEST_TO_STRING_OVERLOAD(int long long unsigned, "%llu")

String toString(std::nullptr_t) { return "NULL"; }

#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183
String toString(const std::string& in) { return in.c_str(); }
#endif // VS 2019

Approx::Approx(double value)
        : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100)
        , m_scale(1.0)
        , m_value(value) {}

Approx Approx::operator()(double value) const {
    Approx approx(value);
    approx.epsilon(m_epsilon);
    approx.scale(m_scale);
    return approx;
}

Approx& Approx::epsilon(double newEpsilon) {
    m_epsilon = newEpsilon;
    return *this;
}
Approx& Approx::scale(double newScale) {
    m_scale = newScale;
    return *this;
}

bool operator==(double lhs, const Approx& rhs) {
    // Thanks to Richard Harris for his help refining this formula
    return std::fabs(lhs - rhs.m_value) <
           rhs.m_epsilon * (rhs.m_scale + std::max<double>(std::fabs(lhs), std::fabs(rhs.m_value)));
}
bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); }
bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); }
bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; }
bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; }
bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; }
bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; }
bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; }
bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; }
bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; }
bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }

String toString(const Approx& in) {
    // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
    return "Approx( " + doctest::toString(in.m_value) + " )";
}
const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); }

} // namespace doctest

#ifdef DOCTEST_CONFIG_DISABLE
namespace doctest {
Context::Context(int, const char* const*) {}
Context::~Context() = default;
void Context::applyCommandLine(int, const char* const*) {}
void Context::addFilter(const char*, const char*) {}
void Context::clearFilters() {}
void Context::setOption(const char*, bool) {}
void Context::setOption(const char*, int) {}
void Context::setOption(const char*, const char*) {}
bool Context::shouldExit() { return false; }
void Context::setAsDefaultForAssertsOutOfTestCases() {}
void Context::setAssertHandler(detail::assert_handler) {}
void Context::setCout(std::ostream* out) {}
int  Context::run() { return 0; }

IReporter::~IReporter() = default;

int                         IReporter::get_num_active_contexts() { return 0; }
const IContextScope* const* IReporter::get_active_contexts() { return nullptr; }
int                         IReporter::get_num_stringified_contexts() { return 0; }
const String*               IReporter::get_stringified_contexts() { return nullptr; }

int registerReporter(const char*, int, IReporter*) { return 0; }

} // namespace doctest
#else // DOCTEST_CONFIG_DISABLE

#if !defined(DOCTEST_CONFIG_COLORS_NONE)
#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI)
#ifdef DOCTEST_PLATFORM_WINDOWS
#define DOCTEST_CONFIG_COLORS_WINDOWS
#else // linux
#define DOCTEST_CONFIG_COLORS_ANSI
#endif // platform
#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI
#endif // DOCTEST_CONFIG_COLORS_NONE

namespace doctest_detail_test_suite_ns {
// holds the current test suite
doctest::detail::TestSuite& getCurrentTestSuite() {
    static doctest::detail::TestSuite data{};
    return data;
}
} // namespace doctest_detail_test_suite_ns

namespace doctest {
namespace {
    // the int (priority) is part of the key for automatic sorting - sadly one can register a
    // reporter with a duplicate name and a different priority but hopefully that won't happen often :|
    typedef std::map<std::pair<int, String>, reporterCreatorFunc> reporterMap;

    reporterMap& getReporters() {
        static reporterMap data;
        return data;
    }
    reporterMap& getListeners() {
        static reporterMap data;
        return data;
    }
} // namespace
namespace detail {
#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...)                                           \
    for(auto& curr_rep : g_cs->reporters_currently_used)                                           \
    curr_rep->function(__VA_ARGS__)

    bool checkIfShouldThrow(assertType::Enum at) {
        if(at & assertType::is_require) //!OCLINT bitwise operator in conditional
            return true;

        if((at & assertType::is_check) //!OCLINT bitwise operator in conditional
           && getContextOptions()->abort_after > 0 &&
           (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >=
                   getContextOptions()->abort_after)
            return true;

        return false;
    }

#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
    DOCTEST_NORETURN void throwException() {
        g_cs->shouldLogCurrentException = false;
        throw TestFailureException();
    } // NOLINT(cert-err60-cpp)
#else // DOCTEST_CONFIG_NO_EXCEPTIONS
    void throwException() {}
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
} // namespace detail

namespace {
    using namespace detail;
    // matching of a string against a wildcard mask (case sensitivity configurable) taken from
    // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing
    int wildcmp(const char* str, const char* wild, bool caseSensitive) {
        const char* cp = str;
        const char* mp = wild;

        while((*str) && (*wild != '*')) {
            if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) &&
               (*wild != '?')) {
                return 0;
            }
            wild++;
            str++;
        }

        while(*str) {
            if(*wild == '*') {
                if(!*++wild) {
                    return 1;
                }
                mp = wild;
                cp = str + 1;
            } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) ||
                      (*wild == '?')) {
                wild++;
                str++;
            } else {
                wild = mp;   //!OCLINT parameter reassignment
                str  = cp++; //!OCLINT parameter reassignment
            }
        }

        while(*wild == '*') {
            wild++;
        }
        return !*wild;
    }

    //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html
    //unsigned hashStr(unsigned const char* str) {
    //    unsigned long hash = 5381;
    //    char          c;
    //    while((c = *str++))
    //        hash = ((hash << 5) + hash) + c; // hash * 33 + c
    //    return hash;
    //}

    // checks if the name matches any of the filters (and can be configured what to do when empty)
    bool matchesAny(const char* name, const std::vector<String>& filters, bool matchEmpty,
                    bool caseSensitive) {
        if(filters.empty() && matchEmpty)
            return true;
        for(auto& curr : filters)
            if(wildcmp(name, curr.c_str(), caseSensitive))
                return true;
        return false;
    }
} // namespace
namespace detail {

    Subcase::Subcase(const String& name, const char* file, int line)
            : m_signature({name, file, line}) {
        auto* s = g_cs;

        // check subcase filters
        if(s->subcasesStack.size() < size_t(s->subcase_filter_levels)) {
            if(!matchesAny(m_signature.m_name.c_str(), s->filters[6], true, s->case_sensitive))
                return;
            if(matchesAny(m_signature.m_name.c_str(), s->filters[7], false, s->case_sensitive))
                return;
        }
        
        // if a Subcase on the same level has already been entered
        if(s->subcasesStack.size() < size_t(s->subcasesCurrentMaxLevel)) {
            s->should_reenter = true;
            return;
        }

        // push the current signature to the stack so we can check if the
        // current stack + the current new subcase have been traversed
        s->subcasesStack.push_back(m_signature);
        if(s->subcasesPassed.count(s->subcasesStack) != 0) {
            // pop - revert to previous stack since we've already passed this
            s->subcasesStack.pop_back();
            return;
        }

        s->subcasesCurrentMaxLevel = s->subcasesStack.size();
        m_entered = true;

        DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature);
    }

    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17
    DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
    DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")

    Subcase::~Subcase() {
        if(m_entered) {
            // only mark the subcase stack as passed if no subcases have been skipped
            if(g_cs->should_reenter == false)
                g_cs->subcasesPassed.insert(g_cs->subcasesStack);
            g_cs->subcasesStack.pop_back();

#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
            if(std::uncaught_exceptions() > 0
#else
            if(std::uncaught_exception()
#endif
            && g_cs->shouldLogCurrentException) {
                DOCTEST_ITERATE_THROUGH_REPORTERS(
                        test_case_exception, {"exception thrown in subcase - will translate later "
                                              "when the whole test case has been exited (cannot "
                                              "translate while there is an active exception)",
                                              false});
                g_cs->shouldLogCurrentException = false;
            }
            DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY);
        }
    }

    DOCTEST_CLANG_SUPPRESS_WARNING_POP
    DOCTEST_GCC_SUPPRESS_WARNING_POP
    DOCTEST_MSVC_SUPPRESS_WARNING_POP

    Subcase::operator bool() const { return m_entered; }

    Result::Result(bool passed, const String& decomposition)
            : m_passed(passed)
            , m_decomp(decomposition) {}

    ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at)
            : m_at(at) {}

    TestSuite& TestSuite::operator*(const char* in) {
        m_test_suite = in;
        return *this;
    }

    TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite,
                       const char* type, int template_id) {
        m_file              = file;
        m_line              = line;
        m_name              = nullptr; // will be later overridden in operator*
        m_test_suite        = test_suite.m_test_suite;
        m_description       = test_suite.m_description;
        m_skip              = test_suite.m_skip;
        m_no_breaks         = test_suite.m_no_breaks;
        m_no_output         = test_suite.m_no_output;
        m_may_fail          = test_suite.m_may_fail;
        m_should_fail       = test_suite.m_should_fail;
        m_expected_failures = test_suite.m_expected_failures;
        m_timeout           = test_suite.m_timeout;

        m_test        = test;
        m_type        = type;
        m_template_id = template_id;
    }

    TestCase::TestCase(const TestCase& other)
            : TestCaseData() {
        *this = other;
    }

    DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function
    DOCTEST_MSVC_SUPPRESS_WARNING(26437)           // Do not slice
    TestCase& TestCase::operator=(const TestCase& other) {
        static_cast<TestCaseData&>(*this) = static_cast<const TestCaseData&>(other);

        m_test        = other.m_test;
        m_type        = other.m_type;
        m_template_id = other.m_template_id;
        m_full_name   = other.m_full_name;

        if(m_template_id != -1)
            m_name = m_full_name.c_str();
        return *this;
    }
    DOCTEST_MSVC_SUPPRESS_WARNING_POP

    TestCase& TestCase::operator*(const char* in) {
        m_name = in;
        // make a new name with an appended type for templated test case
        if(m_template_id != -1) {
            m_full_name = String(m_name) + m_type;
            // redirect the name to point to the newly constructed full name
            m_name = m_full_name.c_str();
        }
        return *this;
    }

    bool TestCase::operator<(const TestCase& other) const {
        // this will be used only to differentiate between test cases - not relevant for sorting
        if(m_line != other.m_line)
            return m_line < other.m_line;
        const int name_cmp = strcmp(m_name, other.m_name);
        if(name_cmp != 0)
            return name_cmp < 0;
        const int file_cmp = m_file.compare(other.m_file);
        if(file_cmp != 0)
            return file_cmp < 0;
        return m_template_id < other.m_template_id;
    }

    // all the registered tests
    std::set<TestCase>& getRegisteredTests() {
        static std::set<TestCase> data;
        return data;
    }
} // namespace detail
namespace {
    using namespace detail;
    // for sorting tests by file/line
    bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
        // this is needed because MSVC gives different case for drive letters
        // for __FILE__ when evaluated in a header and a source file
        const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC));
        if(res != 0)
            return res < 0;
        if(lhs->m_line != rhs->m_line)
            return lhs->m_line < rhs->m_line;
        return lhs->m_template_id < rhs->m_template_id;
    }

    // for sorting tests by suite/file/line
    bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {
        const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
        if(res != 0)
            return 
Download .txt
gitextract_hqqsamgp/

├── .github/
│   └── workflows/
│       ├── analysis.yml
│       ├── docs.yaml
│       └── main.yml
├── .gitignore
├── 3rdparty/
│   └── doctest/
│       └── doctest.h
├── CMakeLists.txt
├── ChangeLog
├── INSTALL
├── LICENSE
├── README.md
├── STYLE.md
├── cmake/
│   └── UseLATEX.cmake
├── doc/
│   ├── CMakeLists.txt
│   ├── ChangeLog
│   ├── ipr.bib
│   ├── macro.tex
│   ├── ref.tex
│   └── user-guide.tex
├── include/
│   ├── ChangeLog
│   └── ipr/
│       ├── impl
│       ├── input
│       ├── lexer
│       ├── node-category
│       ├── std-preamble
│       └── utility-impl
├── infra/
│   └── Analysis.ruleset
├── src/
│   ├── ChangeLog
│   ├── builtin.def
│   ├── cxx-ipr-io.cxx
│   ├── cxx-ipr-io.ixx
│   ├── cxx-ipr-syntax.ixx
│   ├── cxx-ipr-traversal.cxx
│   ├── cxx-ipr-traversal.ixx
│   ├── cxx-ipr-vocabulary.ixx
│   ├── cxx-ipr.cxx
│   ├── cxx-ipr.ixx
│   ├── impl.cxx
│   ├── input.cxx
│   └── utility.cxx
└── tests/
    ├── CMakeLists.txt
    └── unit-tests/
        ├── CMakeLists.txt
        ├── conversions.cxx
        ├── lines.cxx
        ├── main.cxx
        ├── phased-eval.cxx
        ├── region-owner.cxx
        ├── simple.cxx
        ├── specifiers.cxx
        ├── warehouse.cxx
        └── words.cxx
Download .txt
Showing preview only (271K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (573 symbols across 7 files)

FILE: 3rdparty/doctest/doctest.h
  function namespace (line 389) | namespace doctest { namespace detail {
  function namespace (line 455) | namespace std { // NOLINT (cert-dcl58-cpp)
  function namespace (line 487) | namespace doctest {
  function String (line 985) | String convert(U* p) {
  function String (line 995) | static String convert(R C::*p) {
  type typename (line 1031) | typedef typename detail::underlying_type<T>::type UT;
  function class (line 1040) | class DOCTEST_INTERFACE Approx
  function namespace (line 1127) | namespace detail {
  function Result (line 1212) | struct DOCTEST_INTERFACE Result
  function namespace (line 1527) | namespace assertAction {
  function binary_assert (line 1569) | bool binary_assert(assertType::Enum at, const char* file, int line,
  function unary_assert (line 1584) | bool unary_assert(assertType::Enum at, const char* file, int line,
  function IExceptionTranslator (line 1600) | struct DOCTEST_INTERFACE IExceptionTranslator
  function translate (line 1614) | bool translate(String& res) const override {
  function convert (line 1638) | void convert(std::ostream* s, const T& in) {
  function convert (line 1644) | static void convert(std::ostream* s, const char* in) { *s << String(in); }
  type StringStreamBase (line 1648) | struct StringStreamBase
  function convert (line 1651) | void convert(std::ostream* s, const T& in) {
  function need_to_destroy (line 1694) | bool need_to_destroy{true};
  function stringify (line 1706) | void stringify(std::ostream* s) const override { lambda_(s); }
  function MessageBuilder (line 1715) | struct DOCTEST_INTERFACE MessageBuilder : public MessageData
  function namespace (line 1785) | namespace doctest_detail_test_suite_ns {
  function namespace (line 1789) | namespace doctest {
  function throw_exception (line 3085) | void throw_exception(Ex const& e) {
  function stricmp (line 3102) | int stricmp(const char* a, const char* b) {
  type Endianness (line 3124) | struct Endianness
  function String (line 3144) | String rawMemoryToString(const void* object, unsigned size) {
  function DOCTEST_THREAD_LOCAL (line 3160) | DOCTEST_THREAD_LOCAL class
  function String (line 3187) | String tlssPop() {
  function namespace (line 3193) | namespace timer_large_integer
  type timer_large_integer (line 3203) | typedef timer_large_integer::type ticks_t;
  function ticks_t (line 3206) | ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); }
  function ticks_t (line 3208) | ticks_t getCurrentTicks() {
  function ticks_t (line 3219) | ticks_t getCurrentTicks() {
  type Timer (line 3226) | struct Timer
  type CacheLineAlignedAtomic (line 3258) | struct CacheLineAlignedAtomic
  function resetRunData (line 3353) | void resetRunData() {
  function finalizeTestCaseData (line 3364) | void finalizeTestCaseData() {
  function setOnHeap (line 3432) | void String::setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last])...
  function setLast (line 3433) | void String::setLast(unsigned in) { buf[last] = char(in); }
  function copy (line 3435) | void String::copy(const String& other) {
  function const (line 3545) | char String::operator[](unsigned i) const {
  function compare (line 3569) | int String::compare(const char* other, bool no_case) const {
  function compare (line 3575) | int String::compare(const String& other, bool no_case) const {
  function operator (line 3585) | bool operator< (const String& lhs, const String& rhs) { return lhs.compa...
  function operator (line 3586) | bool operator> (const String& lhs, const String& rhs) { return lhs.compa...
  function color_to_stream (line 3594) | void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISAB...
  function namespace (line 3597) | namespace Color {
  function String (line 3709) | String toString(char* in) { return toString(static_cast<const char*>(in)...
  function String (line 3711) | String toString(const char* in) { return String("\"") + (in ? in : "{nul...
  function String (line 3713) | String toString(bool in) { return in ? "true" : "false"; }
  function String (line 3714) | String toString(float in) { return fpToString(in, 5) + "f"; }
  function String (line 3715) | String toString(double in) { return fpToString(in, 10); }
  function String (line 3716) | String toString(double long in) { return fpToString(in, 15); }
  function String (line 3737) | String toString(std::nullptr_t) { return "NULL"; }
  function String (line 3741) | String toString(const std::string& in) { return in.c_str(); }
  function Approx (line 3749) | Approx Approx::operator()(double value) const {
  function String (line 3782) | String toString(const Approx& in) {
  function ContextOptions (line 3786) | const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DIS...
  function namespace (line 3791) | namespace doctest {
  function namespace (line 3828) | namespace doctest_detail_test_suite_ns {
  function namespace (line 3836) | namespace doctest {
  function fileOrderComparator (line 4094) | bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  function suiteOrderComparator (line 4106) | bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  function nameOrderComparator (line 4114) | bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) {
  function color_to_stream (line 4122) | void color_to_stream(std::ostream& s, Color::Enum code) {
  function DOCTEST_CLANG_SUPPRESS_WARNING_POP (line 4195) | DOCTEST_CLANG_SUPPRESS_WARNING_POP
  function isDebuggerActive (line 4272) | bool isDebuggerActive() {
  function isDebuggerActive (line 4295) | bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; }
  function isDebuggerActive (line 4297) | bool isDebuggerActive() { return false; }
  function registerExceptionTranslatorImpl (line 4301) | void registerExceptionTranslatorImpl(const IExceptionTranslator* et) {
  function toStream (line 4308) | void toStream(std::ostream* s, char* in) { *s << in; }
  function toStream (line 4309) | void toStream(std::ostream* s, const char* in) { *s << in; }
  function toStream (line 4311) | void toStream(std::ostream* s, bool in) { *s << std::boolalpha << in << ...
  function toStream (line 4312) | void toStream(std::ostream* s, float in) { *s << in; }
  function toStream (line 4313) | void toStream(std::ostream* s, double in) { *s << in; }
  function toStream (line 4314) | void toStream(std::ostream* s, double long in) { *s << in; }
  function toStream (line 4316) | void toStream(std::ostream* s, char in) { *s << in; }
  function toStream (line 4317) | void toStream(std::ostream* s, char signed in) { *s << in; }
  function toStream (line 4318) | void toStream(std::ostream* s, char unsigned in) { *s << in; }
  function toStream (line 4319) | void toStream(std::ostream* s, int short in) { *s << in; }
  function toStream (line 4320) | void toStream(std::ostream* s, int short unsigned in) { *s << in; }
  function toStream (line 4321) | void toStream(std::ostream* s, int in) { *s << in; }
  function toStream (line 4322) | void toStream(std::ostream* s, int unsigned in) { *s << in; }
  function toStream (line 4323) | void toStream(std::ostream* s, int long in) { *s << in; }
  function toStream (line 4324) | void toStream(std::ostream* s, int long unsigned in) { *s << in; }
  function toStream (line 4325) | void toStream(std::ostream* s, int long long in) { *s << in; }
  function toStream (line 4326) | void toStream(std::ostream* s, int long long unsigned in) { *s << in; }
  function DOCTEST_CLANG_SUPPRESS_WARNING_POP (line 4362) | DOCTEST_CLANG_SUPPRESS_WARNING_POP
  function addAssert (line 4622) | void addAssert(assertType::Enum at) {
  function addFailedAssert (line 4627) | void addFailedAssert(assertType::Enum at) {
  function reportFatal (line 4633) | void reportFatal(const std::string& message) {
  function namespace (line 4651) | namespace detail {
  function setResult (line 4671) | void ResultBuilder::setResult(const Result& res) {
  function translateException (line 4676) | void ResultBuilder::translateException() {
  function log (line 4681) | bool ResultBuilder::log() {
  function failed_out_of_a_testing_context (line 4716) | void failed_out_of_a_testing_context(const AssertData& ad) {
  function decomp_assert (line 4723) | bool decomp_assert(assertType::Enum at, const char* file, int line, cons...
  function log (line 4752) | bool MessageBuilder::log() {
  function react (line 4772) | void MessageBuilder::react() {
  function class (line 4787) | class XmlEncode {
  function class (line 4802) | class XmlWriter {
  function trailingBytes (line 4883) | size_t trailingBytes(unsigned char c) {
  function headerValue (line 4896) | uint32_t headerValue(unsigned char c) {
  function hexEscapeChar (line 4909) | void hexEscapeChar(std::ostream& os, unsigned char c) {
  function encodeTo (line 4924) | void XmlEncode::encodeTo( std::ostream& os ) const {
  function ensureTagClosed (line 5138) | void XmlWriter::ensureTagClosed() {
  function writeDeclaration (line 5145) | void XmlWriter::writeDeclaration() {
  function newlineIfNecessary (line 5149) | void XmlWriter::newlineIfNecessary() {
  function IReporter (line 5162) | struct XmlReporter : public IReporter
  function fulltext_log_assert_to_stream (line 5397) | void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) {
  function IReporter (line 5452) | struct JUnitReporter : public IReporter
  type JUnitTestMessage (line 5482) | struct JUnitTestMessage
  type JUnitTestCase (line 5493) | struct JUnitTestCase
  function add (line 5503) | void add(const std::string& classname, const std::string& name) {
  function appendSubcaseNamesToLastTestcase (line 5507) | void appendSubcaseNamesToLastTestcase(std::vector<String> nameStack) {
  function line (line 5545) | unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; }
  function report_query (line 5551) | void report_query(const QueryData&) override {}
  function test_run_start (line 5553) | void test_run_start() override {}
  function test_run_end (line 5555) | void test_run_end(const TestRunStats& p) override {
  function test_case_start (line 5602) | void test_case_start(const TestCaseData& in) override {
  function test_case_reenter (line 5607) | void test_case_reenter(const TestCaseData& in) override {
  function test_case_end (line 5616) | void test_case_end(const CurrentTestCaseStats&) override {
  function test_case_exception (line 5622) | void test_case_exception(const TestCaseException& e) override {
  function subcase_start (line 5627) | void subcase_start(const SubcaseSignature& in) override {
  function subcase_end (line 5631) | void subcase_end() override {}
  function log_assert (line 5633) | void log_assert(const AssertData& rb) override {
  function log_message (line 5648) | void log_message(const MessageData&) override {}
  function test_case_skipped (line 5650) | void test_case_skipped(const TestCaseData&) override {}
  function log_contexts (line 5652) | void log_contexts(std::ostringstream& s) {
  type Whitespace (line 5669) | struct Whitespace
  function separator_to_stream (line 5706) | void separator_to_stream() {
  function log_contexts (line 5730) | void log_contexts() {
  function logTestStart (line 5754) | void logTestStart() {
  function printVersion (line 5786) | void printVersion() {
  function printIntro (line 5792) | void printIntro() {
  function printHelp (line 5800) | void printHelp() {
  function printReporters (line 5919) | auto printReporters = [this] (const reporterMap& reporters, const char* ...
  function ConsoleReporter (line 6138) | struct DebugOutputWindowReporter : public ConsoleReporter
  function parseFlag (line 6222) | bool parseFlag(int argc, const char* const* argv, const char* pattern) {
  function parseCommaSepArgs (line 6227) | bool parseCommaSepArgs(int argc, const char* const* argv, const char* pa...
  type optionType (line 6272) | enum optionType
  function parseIntOption (line 6279) | bool parseIntOption(int argc, const char* const* argv, const char* patte...
  function applyCommandLine (line 6327) | void Context::applyCommandLine(int argc, const char* const* argv) {
  function parseArgs (line 6334) | void Context::parseArgs(int argc, const char* const* argv, bool withDefa...
  function addFilter (line 6460) | void Context::addFilter(const char* filter, const char* value) { setOpti...
  function DOCTEST_MSVC_SUPPRESS_WARNING_POP (line 6729) | DOCTEST_MSVC_SUPPRESS_WARNING_POP
  function get_num_active_contexts (line 6780) | int IReporter::get_num_active_contexts() { return detail::g_infoContexts...
  function IContextScope (line 6781) | const IContextScope* const* IReporter::get_active_contexts() {
  function get_num_stringified_contexts (line 6785) | int IReporter::get_num_stringified_contexts() { return detail::g_cs->str...
  function String (line 6786) | const String* IReporter::get_stringified_contexts() {
  function namespace (line 6790) | namespace detail {
  function main (line 6805) | int main(int argc, char** argv) { return doctest::Context(argc, argv).ru...

FILE: src/cxx-ipr-io.cxx
  type ipr (line 22) | namespace ipr {
    function Printer (line 25) | static Printer& sequenced(Printer& pp, const Sequence<T>& s, F f)
    function Printer (line 33) | static Printer& comma_separated(Printer& pp, const Sequence<T>& s)
    function Printer (line 45) | Printer& operator<<(Printer& p, Mapping_level x)
    function Printer (line 52) | Printer& operator<<(Printer& p, Decl_position x)
    type pp_base (line 59) | struct pp_base : Constant_visitor<Missing_overrider> {
      method pp_base (line 60) | explicit pp_base(Printer& p) : pp(p) { }
      method visit (line 62) | void visit(const Type& t) override { visit(as<Expr>(t)); }
      method visit (line 63) | void visit(const Decl& d) override { visit(as<Expr>(d)); }
    function Printer (line 77) | Printer&
    type Token_helper (line 93) | struct Token_helper {
      method Token_helper (line 95) | Token_helper(T t) : value(t) { }
    function token (line 99) | inline Token_helper<T>
    function Printer (line 106) | inline Printer&
    function Printer (line 112) | inline Printer&
    type needs_newline (line 118) | struct needs_newline { }
    function Printer (line 120) | inline Printer&
    type newline (line 127) | struct newline { }
    function Printer (line 129) | Printer&
    function Printer (line 141) | static inline Printer&
    function Printer (line 149) | static inline Printer&
    function Printer (line 157) | static inline Printer&
    type xpr_initializer (line 163) | struct xpr_initializer {
      method xpr_initializer (line 165) | explicit xpr_initializer(const ipr::Expr& e) : expr(e) { }
    type indentation (line 170) | struct indentation {
      method indentation (line 172) | indentation(int n) : amount(n) { }
    function Printer (line 175) | inline Printer&
    type newline_and_indent (line 182) | struct newline_and_indent {
      method newline_and_indent (line 184) | newline_and_indent(int n = 0) : indentation(n) { }
    function Printer (line 187) | inline Printer&
    type xpr_primary_expr (line 194) | struct xpr_primary_expr {
      method xpr_primary_expr (line 196) | explicit xpr_primary_expr(const Expr& e) : expr(e) { }
    type xpr_cast_expr (line 200) | struct xpr_cast_expr {
      method xpr_cast_expr (line 202) | xpr_cast_expr(const Expr& e) : expr(e) { }
    type xpr_assignment_expression (line 206) | struct xpr_assignment_expression {
      method xpr_assignment_expression (line 208) | xpr_assignment_expression(const Expr& e) : expr(e) { }
    type xpr_exception_spec (line 213) | struct xpr_exception_spec {
    type xpr_identifier (line 219) | struct xpr_identifier {
      method xpr_identifier (line 222) | explicit xpr_identifier(const ipr::String& s) : txt{s.characters()} { }
      method xpr_identifier (line 225) | explicit xpr_identifier(const char8_t (&s)[N]) : txt{s} { }
    function Printer (line 228) | static inline Printer&
    function Printer (line 238) | Printer&
    function Printer (line 244) | Printer& operator<<(Printer& pp, const Logogram& l)
    type xpr (line 268) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    type xpr_name (line 361) | struct xpr_name {
      method xpr_name (line 363) | explicit xpr_name(const Name& n) : name(n) { }
      method xpr_name (line 364) | explicit xpr_name(const Decl& d) : name(d.name()) { }
    function Printer (line 367) | static inline Printer&
    type xpr (line 382) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 473) | static inline Printer&
    type xpr_postfix_expr (line 482) | struct xpr_postfix_expr {
      method xpr_postfix_expr (line 484) | explicit xpr_postfix_expr(const Expr& e) : expr(e) { }
    function new_style_cast (line 490) | void
    type xpr (line 498) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 591) | static inline Printer&
    function unary_operation (line 606) | inline void
    type xpr (line 612) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    type xpr (line 674) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 688) | static inline Printer&
    type xpr_pm_expr (line 701) | struct xpr_pm_expr {
      method xpr_pm_expr (line 703) | explicit xpr_pm_expr(const Expr& e) : expr(e) { }
    function offset_with_pm (line 709) | static void
    type xpr (line 717) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 726) | static inline Printer&
    function binary_expression (line 737) | inline void
    type xpr_mul_expr (line 751) | struct xpr_mul_expr {
      method xpr_mul_expr (line 753) | explicit xpr_mul_expr(const Expr& e) : expr(e) { }
    type xpr (line 756) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 775) | static inline Printer&
    type xpr_add_expr (line 788) | struct xpr_add_expr {
      method xpr_add_expr (line 790) | explicit xpr_add_expr(const Expr& e) : expr(e) { }
    type xpr (line 793) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 809) | static inline Printer&
    type xpr_shift_expr (line 823) | struct xpr_shift_expr {
      method xpr_shift_expr (line 825) | explicit xpr_shift_expr(const Expr& e) : expr(e) { }
    type xpr (line 828) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 844) | static inline Printer&
    type xpr_rel_expr (line 860) | struct xpr_rel_expr {
      method xpr_rel_expr (line 862) | explicit xpr_rel_expr(const Expr& e) : expr(e) { }
    type xpr (line 865) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 891) | static inline Printer&
    type xpr_eq_expr (line 904) | struct xpr_eq_expr {
      method xpr_eq_expr (line 906) | explicit xpr_eq_expr(const Expr& e) : expr(e) { }
    type xpr (line 909) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 925) | static inline Printer&
    type xpr_and_expr (line 938) | struct xpr_and_expr {
      method xpr_and_expr (line 940) | explicit xpr_and_expr(const Expr& e) : expr(e) { }
    type xpr (line 943) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 954) | static inline Printer&
    type xpr_xor_expr (line 966) | struct xpr_xor_expr {
      method xpr_xor_expr (line 968) | explicit xpr_xor_expr(const Expr& e) : expr(e) { }
    type xpr (line 971) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 982) | static inline Printer&
    type xpr_ior_expr (line 995) | struct xpr_ior_expr {
      method xpr_ior_expr (line 997) | explicit xpr_ior_expr(const Expr& e) : expr(e) { }
    type xpr (line 1000) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 1011) | static inline Printer&
    type xpr_land_expr (line 1024) | struct xpr_land_expr {
      method xpr_land_expr (line 1026) | explicit xpr_land_expr(const Expr& e) : expr(e) { }
    type xpr (line 1029) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 1040) | static inline Printer&
    type xpr_lor_expr (line 1053) | struct xpr_lor_expr {
      method xpr_lor_expr (line 1055) | explicit xpr_lor_expr(const Expr& e) : expr(e) { }
    type xpr (line 1058) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      type Assignment_expr (line 1147) | struct Assignment_expr : xpr::Cond_expr {
        method Assignment_expr (line 1148) | Assignment_expr(Printer& p) : xpr::Cond_expr(p) { }
        method visit (line 1150) | void visit(const Assign& e) final
        method visit (line 1155) | void visit(const Plus_assign& e) final
        method visit (line 1160) | void visit(const Bitand_assign& e) final
        method visit (line 1165) | void visit(const Bitor_assign& e) final
        method visit (line 1170) | void visit(const Bitxor_assign& e) final
        method visit (line 1175) | void visit(const Div_assign& e) final
        method visit (line 1180) | void visit(const Modulo_assign& e) final
        method visit (line 1185) | void visit(const Mul_assign& e) final
        method visit (line 1190) | void visit(const Lshift_assign& e) final
        method visit (line 1195) | void visit(const Rshift_assign& e) final
        method visit (line 1200) | void visit(const Minus_assign& e) final
        method visit (line 1205) | void visit(const Throw& e) final
        method visit (line 1211) | void visit(const Mapping& m) final
      type Stmt (line 1538) | struct Stmt : xpr::Assignment_expr {
        method Stmt (line 1539) | Stmt(Printer& p) : xpr::Assignment_expr(p) { }
        method visit (line 1541) | void visit(const Expr_stmt& e) final
        method visit (line 1548) | void visit(const Labeled_stmt& s) final
        method visit (line 1564) | void visit(const Block& s) final
        method visit (line 1575) | void visit(const Ctor_body& b) final
        method visit (line 1585) | void visit(const If& s) final
        method visit (line 1601) | void visit(const Return& s) final
        method visit (line 1610) | void visit(const Switch& s) final
        method visit (line 1620) | void visit(const While& s) final
        method visit (line 1630) | void visit(const Do& s) final
        method visit (line 1642) | void visit(const For& s) final
        method visit (line 1657) | void visit(const For_in& s) final
        method visit (line 1670) | void visit(const Break&) final
        method visit (line 1677) | void visit(const Continue&) final
        method visit (line 1684) | void visit(const Goto& s) final
        method visit (line 1693) | void visit(const Handler& s) final
        method visit (line 1705) | void visit(const Decl& d) override
      type Location_printer (line 1713) | struct Location_printer
        method print (line 1733) | static void print(Printer& printer, const ipr::Node& node)
      type Decl (line 1770) | struct Decl : xpr::Stmt {
        method Decl (line 1771) | Decl(Printer& p) : xpr::Stmt(p) { }
        method visit (line 1773) | void visit(const ipr::Alias& d) final
        method visit (line 1782) | void visit(const ipr::Decl& d) override
        method visit (line 1797) | void visit(const Typedecl& d) final
        method visit (line 1807) | void visit(const Enumerator& e) final
        method visit (line 1814) | void visit(const Bitfield& b) final
        method visit (line 1823) | void visit(const Base_type& b) final
        method visit (line 1828) | void visit(const Fundecl& f) final
        method visit (line 1844) | void visit(const Template& m) final
    function Printer (line 1069) | static inline Printer&
    type xpr (line 1082) | namespace xpr {
      type Name (line 269) | struct Name : pp_base {
        method Name (line 270) | explicit Name(Printer& p) : pp_base(p) { }
        method visit (line 272) | void visit(const Identifier& id) final
        method visit (line 285) | void visit(const Operator& o) final
        method visit (line 303) | void visit(const Conversion& c) final
        method visit (line 314) | void visit(const Suffix& s) final
        method visit (line 323) | void visit(const Type_id& n) final
        method visit (line 332) | void visit(const Scope_ref& n) final
        method visit (line 339) | void visit(const Template_id& n) final
        method visit (line 347) | void visit(const Ctor_name&) final
        method visit (line 354) | void visit(const Dtor_name&) final
      type Primary_expr (line 383) | struct Primary_expr : xpr::Name {
        method Primary_expr (line 384) | Primary_expr(Printer& pp) : xpr::Name(pp) { }
        method visit (line 386) | void visit(const Label& l) final { xpr::Name::visit(l.name()); }
        method visit (line 387) | void visit(const Id_expr& id) final { pp << xpr_name{ id.name() }; }
        method visit (line 389) | void visit(const Symbol& s) final { pp << xpr_name{ s.name() }; }
        method visit (line 390) | void visit(const As_type& t) final
        method visit (line 397) | void visit(const Phantom&) final { }
        method visit (line 398) | void visit(const Enclosure& e) final
        method visit (line 404) | void visit(const Expr& e) override
        method visit (line 408) | void visit(const Decl& d) override { d.name().accept(*this); }
      type Postfix_expr (line 501) | struct Postfix_expr : xpr::Primary_expr {
        method Postfix_expr (line 502) | Postfix_expr(Printer& pp) : xpr::Primary_expr(pp) { }
        method visit (line 505) | void visit(const Array_ref& e) final
        method visit (line 512) | void visit(const Dot& e) final
        method visit (line 519) | void visit(const Arrow& e) final
        method visit (line 526) | void visit(const Call& e) final
        method visit (line 532) | void visit(const Construction& e) final
        method visit (line 539) | void visit(const Post_decrement& e) final
        method visit (line 545) | void visit(const Post_increment& e) final
        method visit (line 551) | void visit(const Dynamic_cast& e) final
        method visit (line 557) | void visit(const Static_cast& e) final
        method visit (line 563) | void visit(const Const_cast& e) final
        method visit (line 569) | void visit(const Reinterpret_cast& e) final
        method visit (line 575) | void visit(const Typeid& e) final
        method visit (line 582) | void visit(const Noexcept& e) final
      type Unary_expr (line 613) | struct Unary_expr : xpr::Postfix_expr {
        method Unary_expr (line 614) | Unary_expr(Printer& pp) : xpr::Postfix_expr(pp) { }
        method visit (line 616) | void visit(const Pre_decrement& e) final { unary_operation(pp, e, ...
        method visit (line 618) | void visit(const Pre_increment& e) final { unary_operation(pp, e, ...
        method visit (line 620) | void visit(const Address& e) final { unary_operation(pp, e, "&"); }
        method visit (line 622) | void visit(const Complement& e) final { unary_operation(pp, e, "~"...
        method visit (line 624) | void visit(const Deref& e) final { unary_operation(pp, e, "*"); }
        method visit (line 626) | void visit(const Unary_minus& e) final { unary_operation(pp, e, "-...
        method visit (line 628) | void visit(const Not& e) final { unary_operation(pp, e, "!"); }
        method visit (line 630) | void visit(const Sizeof& e) final
        method visit (line 636) | void visit(const Args_cardinality& e) final
        method visit (line 642) | void visit(const Unary_plus& e) final
        method visit (line 647) | void visit(const New& e) final
        method visit (line 656) | void visit(const Delete& e) final
        method visit (line 663) | void visit(const Array_delete& e) final
      type Cast_expr (line 675) | struct Cast_expr : xpr::Unary_expr {
        method Cast_expr (line 676) | Cast_expr(Printer& p) : xpr::Unary_expr(p) { }
        method visit (line 681) | void visit(const Cast& e) final
      type Pm_expr (line 718) | struct Pm_expr : xpr::Cast_expr {
        method Pm_expr (line 719) | Pm_expr(Printer& p) : xpr::Cast_expr(p) { }
        method visit (line 721) | void visit(const Dot_star& e) final { offset_with_pm(pp, e, ".*"); }
        method visit (line 722) | void visit(const Arrow_star& e) final { offset_with_pm(pp, e, "->*...
      type Mul_expr (line 757) | struct Mul_expr : xpr::Pm_expr {
        method Mul_expr (line 758) | Mul_expr(Printer& p) : xpr::Pm_expr(p) { }
        method visit (line 760) | void visit(const Mul& e) final
        method visit (line 764) | void visit(const Div& e) final
        method visit (line 768) | void visit(const Modulo& e) final
      type Add_expr (line 794) | struct Add_expr : xpr::Mul_expr {
        method Add_expr (line 795) | Add_expr(Printer& p) : xpr::Mul_expr(p) { }
        method visit (line 797) | void visit(const Plus& e) final
        method visit (line 802) | void visit(const Minus& e) final
      type Shift_expr (line 829) | struct Shift_expr : xpr::Add_expr {
        method Shift_expr (line 830) | Shift_expr(Printer& p) : xpr::Add_expr(p) { }
        method visit (line 832) | void visit(const Lshift& e) final
        method visit (line 837) | void visit(const Rshift& e) final
      type Rel_expr (line 866) | struct Rel_expr : xpr::Shift_expr {
        method Rel_expr (line 867) | Rel_expr(Printer& p) : xpr::Shift_expr(p) { }
        method visit (line 869) | void visit(const Less& e) final
        method visit (line 874) | void visit(const Less_equal& e) final
        method visit (line 879) | void visit(const Greater& e) final
        method visit (line 884) | void visit(const Greater_equal& e) final
      type Eq_expr (line 910) | struct Eq_expr : xpr::Rel_expr {
        method Eq_expr (line 911) | Eq_expr(Printer& p) : xpr::Rel_expr(p) { }
        method visit (line 913) | void visit(const Equal& e) final
        method visit (line 918) | void visit(const Not_equal& e) final
      type And_expr (line 944) | struct And_expr : xpr::Eq_expr {
        method And_expr (line 945) | And_expr(Printer& p) : xpr::Eq_expr(p) { }
        method visit (line 947) | void visit(const Bitand& e) final
      type Xor_expr (line 972) | struct Xor_expr : xpr::And_expr {
        method Xor_expr (line 973) | Xor_expr(Printer& p) : xpr::And_expr(p) { }
        method visit (line 975) | void visit(const Bitxor& e) final
      type Ior_expr (line 1001) | struct Ior_expr : xpr::Xor_expr {
        method Ior_expr (line 1002) | Ior_expr(Printer& p) : xpr::Xor_expr(p) { }
        method visit (line 1004) | void visit(const Bitor& e) final
      type Land_expr (line 1030) | struct Land_expr : xpr::Ior_expr {
        method Land_expr (line 1031) | Land_expr(Printer& p) : xpr::Ior_expr(p) { }
        method visit (line 1033) | void visit(const And& e) final
      type Lor_expr (line 1059) | struct Lor_expr : xpr::Land_expr {
        method Lor_expr (line 1060) | Lor_expr(Printer& p) : xpr::Land_expr(p) { }
        method visit (line 1062) | void visit(const Or& e) final
      type Cond_expr (line 1083) | struct Cond_expr : xpr::Lor_expr {
        method Cond_expr (line 1084) | Cond_expr(Printer& p) : xpr::Lor_expr(p) { }
        method visit (line 1086) | void visit(const Conditional& e) final
      typ
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,195K chars).
[
  {
    "path": ".github/workflows/analysis.yml",
    "chars": 2253,
    "preview": "name: Analysis\n\non:\n  push:\n    paths-ignore:\n      - 'doc/**'\n    branches: [ main ]\n  pull_request:\n    paths-ignore:\n"
  },
  {
    "path": ".github/workflows/docs.yaml",
    "chars": 946,
    "preview": "name: Docs\n\non:\n  push:\n    paths:\n      - 'doc/**'\n      - '.github/workflows/docs.yaml'\n    branches: [ main ]\n  pull_"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 4911,
    "preview": "name: Build & Test\n\non:\n  push:\n    paths-ignore:\n      - 'doc/**'\n    branches: [ main ]\n  pull_request:\n    paths-igno"
  },
  {
    "path": ".gitignore",
    "chars": 21,
    "preview": ".vscode/\n.vs/\nbuild/\n"
  },
  {
    "path": "3rdparty/doctest/doctest.h",
    "chars": 309137,
    "preview": "// ====================================================================== lgtm [cpp/missing-header-guard]\n// == DO NOT M"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 2913,
    "preview": "cmake_minimum_required(\n   VERSION 3.31\n)\ninclude(CheckIPOSupported)\n\noption(BUILD_DOC\n   \"Build LaTeX documentation\"\n  "
  },
  {
    "path": "ChangeLog",
    "chars": 4073,
    "preview": "2019-06-26  Gabriel Dos Reis  <gdr@axiomatics.org>\n\n\t* configure.ac: Check for pdflatex.\n\tRegenate build description.\n\t*"
  },
  {
    "path": "INSTALL",
    "chars": 544,
    "preview": "IPR is using CMake as its build system. The default configuration will\nbuild the library and the tests. The tests can be"
  },
  {
    "path": "LICENSE",
    "chars": 1578,
    "preview": "Copyright (C) 2004-2013, Texas A&M University.\nCopyright (C) 2014-2015, Gabriel Dos Reis and Bjarne Stroustrup.\nAll righ"
  },
  {
    "path": "README.md",
    "chars": 2004,
    "preview": "![Build & Test](https://github.com/GabrielDosReis/ipr/actions/workflows/main.yml/badge.svg)\n![Analysis](https://github.c"
  },
  {
    "path": "STYLE.md",
    "chars": 608,
    "preview": "# Coding Style\r\n\r\nUse good judgment, and taste. Appreciate simplicity.\r\n\r\nIn absence of the above, consider the [C++ Cor"
  },
  {
    "path": "cmake/UseLATEX.cmake",
    "chars": 79472,
    "preview": "# File: UseLATEX.cmake\n# CMAKE commands to actually use the LaTeX compiler\n# Version: 2.7.0\n# Author: Kenneth Moreland <"
  },
  {
    "path": "doc/CMakeLists.txt",
    "chars": 125,
    "preview": "add_latex_document(user-guide.tex\n   INPUTS\n      ref.tex\n      macro.tex\n   BIBFILES\n      ipr.bib\n   TARGET_NAME\n     "
  },
  {
    "path": "doc/ChangeLog",
    "chars": 5435,
    "preview": "2019-06-26  Gabriel Dos Reis  <gdr@axiomatics.org>\n\n\t* user-guide.tex: Tidy.\n\t* ref.tex: Likewise.\n\n2019-06-26  Gabriel "
  },
  {
    "path": "doc/ipr.bib",
    "chars": 1406,
    "preview": "%% Books\n@Book{mac-lane01:categories,\n  author = \t {Mac~Lane, S.},\n  title = \t {{Categories} {for} {the} {Working} {Math"
  },
  {
    "path": "doc/macro.tex",
    "chars": 1345,
    "preview": "\\newcommand{\\of}[1]{\\left(#1\\right)}\n\\newcommand{\\ThePivot}{\\textit{The~Pivot}}\n\\newcommand{\\cxxRule}[1]{{\\rmfamily\\itsh"
  },
  {
    "path": "doc/ref.tex",
    "chars": 53264,
    "preview": "\\documentclass[letter,11pt]{article}\n\\usepackage[latin1]{inputenc}\n\\usepackage[T1]{fontenc}\n\\usepackage{mathrsfs}\n%\\usep"
  },
  {
    "path": "doc/user-guide.tex",
    "chars": 58036,
    "preview": "\\documentclass[11pt]{article}\n\\usepackage[latin1]{inputenc}\n\\usepackage[T1]{fontenc}\n\\usepackage{mathrsfs}\n\\usepackage{p"
  },
  {
    "path": "include/ChangeLog",
    "chars": 74200,
    "preview": "2015-12-20  Gabriel Dos Reis  <gdr@axiomatics.org>\n\n\t* ipr/interface: Introduce Module_name, Module_unit,\n\tInterface_uni"
  },
  {
    "path": "include/ipr/impl",
    "chars": 125414,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "include/ipr/input",
    "chars": 9115,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "include/ipr/lexer",
    "chars": 6251,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "include/ipr/node-category",
    "chars": 9080,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "include/ipr/std-preamble",
    "chars": 1192,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "include/ipr/utility-impl",
    "chars": 13145,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "infra/Analysis.ruleset",
    "chars": 1936,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"IPR Ruleset\" Description=\"Warnings to enable for the Microsoft C++"
  },
  {
    "path": "src/ChangeLog",
    "chars": 34359,
    "preview": "2015-11-29  Gabriel Dos Reis  <gdr@axiomatics.org>\n\n\t* impl.cxx: Implement modifications to ipr::Enum.\n\n2010-07-23  Gabr"
  },
  {
    "path": "src/builtin.def",
    "chars": 1067,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copright and license "
  },
  {
    "path": "src/cxx-ipr-io.cxx",
    "chars": 51274,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyright and license"
  },
  {
    "path": "src/cxx-ipr-io.ixx",
    "chars": 4210,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/cxx-ipr-syntax.ixx",
    "chars": 27510,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/cxx-ipr-traversal.cxx",
    "chars": 1620,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyright and license"
  },
  {
    "path": "src/cxx-ipr-traversal.ixx",
    "chars": 2521,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/cxx-ipr-vocabulary.ixx",
    "chars": 28137,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/cxx-ipr.cxx",
    "chars": 13477,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/cxx-ipr.ixx",
    "chars": 106162,
    "preview": "// -*- C++ -*-\n//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyri"
  },
  {
    "path": "src/impl.cxx",
    "chars": 81207,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copyright and license"
  },
  {
    "path": "src/input.cxx",
    "chars": 13911,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copright and license "
  },
  {
    "path": "src/utility.cxx",
    "chars": 2080,
    "preview": "//\n// This file is part of The Pivot framework.\n// Written by Gabriel Dos Reis.\n// See LICENSE for copright and license "
  },
  {
    "path": "tests/CMakeLists.txt",
    "chars": 29,
    "preview": "add_subdirectory(unit-tests)\n"
  },
  {
    "path": "tests/unit-tests/CMakeLists.txt",
    "chars": 1008,
    "preview": "set(TEST_BINARY unittests)\n\nadd_executable(${TEST_BINARY}\n   main.cxx\n   conversions.cxx\n   simple.cxx\n   words.cxx\n   r"
  },
  {
    "path": "tests/unit-tests/conversions.cxx",
    "chars": 5320,
    "preview": "#include <doctest/doctest.h>\n\n#include <ipr/std-preamble>\n\nimport cxx.ipr;\n\n#include <ipr/impl>\n\nTEST_CASE(\"C++ Standard"
  },
  {
    "path": "tests/unit-tests/lines.cxx",
    "chars": 822,
    "preview": "#include \"doctest/doctest.h\"\n#ifdef _WIN32\n#  include <windows.h>\n#  define WIDEN_(S) L ## S\n#  define WIDEN(S) WIDEN_(S"
  },
  {
    "path": "tests/unit-tests/main.cxx",
    "chars": 72,
    "preview": "#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN\n#include <doctest/doctest.h>\n"
  },
  {
    "path": "tests/unit-tests/phased-eval.cxx",
    "chars": 663,
    "preview": "#include \"doctest/doctest.h\"\n\n#include <ipr/std-preamble>\n\nimport cxx.ipr;\n\n#include <ipr/impl>\n\nTEST_CASE(\"asm-declarat"
  },
  {
    "path": "tests/unit-tests/region-owner.cxx",
    "chars": 1744,
    "preview": "#include \"doctest/doctest.h\"\r\n\r\n#include <ipr/std-preamble>\r\n\r\nimport cxx.ipr;\r\nimport cxx.ipr.traversal;\r\n\r\n#include <i"
  },
  {
    "path": "tests/unit-tests/simple.cxx",
    "chars": 3073,
    "preview": "#include <doctest/doctest.h>\n\n#include <ipr/std-preamble>\n#include <sstream>\n\nimport cxx.ipr;\nimport cxx.ipr.io;\n\n#inclu"
  },
  {
    "path": "tests/unit-tests/specifiers.cxx",
    "chars": 2331,
    "preview": "#include <doctest/doctest.h>\n\n#include <ipr/std-preamble>\n#include <ctime>\n#include <ranges>\n#include <sstream>\n\nimport "
  },
  {
    "path": "tests/unit-tests/warehouse.cxx",
    "chars": 1338,
    "preview": "#include \"doctest/doctest.h\"\n\n#include <ipr/std-preamble>\n\nimport cxx.ipr;\n\n#include <ipr/impl>\n\nTEST_CASE(\"warehouse\") "
  },
  {
    "path": "tests/unit-tests/words.cxx",
    "chars": 439,
    "preview": "#include \"doctest/doctest.h\"\r\n\r\n#include <ipr/std-preamble>\r\n\r\nimport cxx.ipr;\r\n\r\n#include <ipr/impl>\r\n\r\nTEST_CASE(\"word"
  }
]

About this extraction

This page contains the full source code of the GabrielDosReis/ipr GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (1.1 MB), approximately 282.2k tokens, and a symbol index with 573 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.

Copied to clipboard!