├── .clang-format ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── ci.yaml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── docs └── images │ ├── badge-c++17.svg │ ├── badge-gitter.svg │ ├── badge-license-MIT.svg │ └── badge-sponsor.svg ├── examples ├── comparison_adapter_std_tuple.hpp ├── comparison_adapter_type_list.hpp ├── comparison_adapters.hpp ├── comparison_main.cpp └── meson.build ├── include ├── meson.build └── mz │ ├── type_list.hpp │ └── type_list.hpp.in ├── meson.build ├── meson_options.txt ├── tests ├── main.cpp └── meson.build └── type_list.code-workspace /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -2 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveMacros: Consecutive 6 | AlignConsecutiveAssignments: Consecutive 7 | AlignConsecutiveBitFields: Consecutive 8 | AlignConsecutiveDeclarations: None 9 | AlignEscapedNewlines: Right 10 | AlignOperands: AlignAfterOperator 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: false 13 | AllowAllConstructorInitializersOnNextLine: false 14 | AllowAllParametersOfDeclarationOnNextLine: false 15 | AllowShortEnumsOnASingleLine: false 16 | AllowShortBlocksOnASingleLine: Never 17 | AllowShortCaseLabelsOnASingleLine: true 18 | AllowShortFunctionsOnASingleLine: None 19 | AllowShortLambdasOnASingleLine: All 20 | AllowShortIfStatementsOnASingleLine: Never 21 | AllowShortLoopsOnASingleLine: false 22 | AlwaysBreakAfterDefinitionReturnType: None 23 | AlwaysBreakAfterReturnType: None 24 | AlwaysBreakBeforeMultilineStrings: false 25 | AlwaysBreakTemplateDeclarations: Yes 26 | AttributeMacros: 27 | - MZ_EMPTY_BASES 28 | - MZ_NODISCARD_CLASS 29 | BinPackArguments: false 30 | BinPackParameters: false 31 | BraceWrapping: 32 | AfterCaseLabel: true 33 | AfterClass: true 34 | AfterControlStatement: Always 35 | AfterEnum: true 36 | AfterFunction: true 37 | AfterNamespace: true 38 | AfterObjCDeclaration: false 39 | AfterStruct: true 40 | AfterUnion: true 41 | AfterExternBlock: true 42 | BeforeCatch: true 43 | BeforeElse: true 44 | BeforeLambdaBody: true 45 | BeforeWhile: true 46 | IndentBraces: false 47 | SplitEmptyFunction: false 48 | SplitEmptyRecord: false 49 | SplitEmptyNamespace: true 50 | BreakBeforeBinaryOperators: NonAssignment 51 | BreakBeforeConceptDeclarations: true 52 | BreakBeforeBraces: Custom 53 | BreakBeforeInheritanceComma: false 54 | BreakInheritanceList: BeforeColon 55 | BreakBeforeTernaryOperators: true 56 | BreakConstructorInitializersBeforeComma: false 57 | BreakConstructorInitializers: BeforeColon 58 | BreakAfterJavaFieldAnnotations: false 59 | BreakStringLiterals: true 60 | ColumnLimit: 120 61 | CommentPragmas: '^([/*!#]|\s*(===|---|clang-format))' 62 | CompactNamespaces: false 63 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 64 | ConstructorInitializerIndentWidth: 4 65 | ContinuationIndentWidth: 4 66 | Cpp11BracedListStyle: false 67 | DeriveLineEnding: false 68 | DerivePointerAlignment: false 69 | DisableFormat: false 70 | EmptyLineBeforeAccessModifier: LogicalBlock 71 | ExperimentalAutoDetectBinPacking: false 72 | FixNamespaceComments: false 73 | ForEachMacros: 74 | - foreach 75 | - Q_FOREACH 76 | - BOOST_FOREACH 77 | StatementAttributeLikeMacros: 78 | - Q_EMIT 79 | IncludeBlocks: Preserve 80 | IncludeCategories: 81 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 82 | Priority: 2 83 | SortPriority: 0 84 | CaseSensitive: false 85 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 86 | Priority: 3 87 | SortPriority: 0 88 | CaseSensitive: false 89 | - Regex: ".*" 90 | Priority: 1 91 | SortPriority: 0 92 | CaseSensitive: false 93 | IncludeIsMainRegex: "(Test)?$" 94 | IncludeIsMainSourceRegex: "" 95 | IndentCaseLabels: true 96 | IndentCaseBlocks: false 97 | IndentGotoLabels: true 98 | IndentPPDirectives: BeforeHash 99 | IndentExternBlock: Indent 100 | IndentRequires: false 101 | IndentWidth: 4 102 | IndentWrappedFunctionNames: false 103 | InsertTrailingCommas: None 104 | JavaScriptQuotes: Leave 105 | JavaScriptWrapImports: true 106 | KeepEmptyLinesAtTheStartOfBlocks: false 107 | MacroBlockBegin: "" 108 | MacroBlockEnd: "" 109 | MaxEmptyLinesToKeep: 1 110 | NamespaceIndentation: All 111 | ObjCBinPackProtocolList: Auto 112 | ObjCBlockIndentWidth: 2 113 | ObjCBreakBeforeNestedBlockParam: true 114 | ObjCSpaceAfterProperty: false 115 | ObjCSpaceBeforeProtocolList: true 116 | PenaltyBreakAssignment: 2 117 | PenaltyBreakBeforeFirstCallParameter: 19 118 | PenaltyBreakComment: 1 119 | PenaltyBreakFirstLessLess: 120 120 | PenaltyBreakString: 1000 121 | PenaltyBreakTemplateDeclaration: 10 122 | PenaltyExcessCharacter: 1000000 123 | PenaltyReturnTypeOnItsOwnLine: 1000000 124 | PenaltyIndentedWhitespace: 0 125 | PointerAlignment: Left 126 | QualifierAlignment: Leave 127 | ReflowComments: true 128 | SortIncludes: false 129 | SortJavaStaticImport: Before 130 | SortUsingDeclarations: false 131 | SpaceAfterCStyleCast: false 132 | SpaceAfterLogicalNot: false 133 | SpaceAfterTemplateKeyword: true 134 | SpaceBeforeAssignmentOperators: true 135 | SpaceBeforeCaseColon: false 136 | SpaceBeforeCpp11BracedList: false 137 | SpaceBeforeCtorInitializerColon: true 138 | SpaceBeforeInheritanceColon: true 139 | SpaceBeforeParens: ControlStatements 140 | SpaceAroundPointerQualifiers: Default 141 | SpaceBeforeRangeBasedForLoopColon: true 142 | SpaceInEmptyBlock: false 143 | SpaceInEmptyParentheses: false 144 | SpacesBeforeTrailingComments: 1 145 | SpacesInAngles: false 146 | SpacesInConditionalStatement: false 147 | SpacesInContainerLiterals: true 148 | SpacesInCStyleCastParentheses: false 149 | SpacesInParentheses: false 150 | SpacesInSquareBrackets: false 151 | SpaceBeforeSquareBrackets: false 152 | BitFieldColonSpacing: Both 153 | Standard: Latest 154 | StatementMacros: 155 | - MZ_ALWAYS_INLINE 156 | - MZ_CONSTRAINED_TEMPLATE 157 | - MZ_CONST_GETTER 158 | - MZ_CONST_INLINE_GETTER 159 | - MZ_NODISCARD 160 | - MZ_NODISCARD_CTOR 161 | - MZ_PURE_GETTER 162 | - MZ_PURE_INLINE_GETTER 163 | TabWidth: 4 164 | TypenameMacros: 165 | UseCRLF: false 166 | UseTab: Always 167 | WhitespaceSensitiveMacros: 168 | - MZ_CONCAT 169 | - MZ_CONSTRAINED_TEMPLATE 170 | - MZ_FOR_EACH 171 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | indent_style = tab 6 | indent_size = 4 7 | tab_width = 4 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | charset = utf-8 11 | 12 | [*.{md,markdown}] 13 | trim_trailing_whitespace = false 14 | 15 | [*.{gitattributes,yaml,yml,vcxproj,vcxproj.filters,sln,rc,clang-format,toml}] 16 | indent_style = space 17 | 18 | [{Doxyfile,Doxyfile-mcss}] 19 | indent_style = space 20 | 21 | [*.{hlsl,rc,sln,vcxproj,vcxproj.filters}] 22 | end_of_line = crlf 23 | 24 | [*.{sln,vcxproj,vcxproj.filters}] 25 | charset = utf-8-bom 26 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf encoding=UTF-8 2 | *.h text eol=lf encoding=UTF-8 linguist-language=C++ 3 | *.hlsl text eol=crlf encoding=UTF-8 4 | *.hpp text eol=lf encoding=UTF-8 linguist-language=C++ 5 | *.rc text eol=crlf encoding=UTF-8 6 | *.sln text eol=crlf encoding=UTF-8-BOM 7 | *.vcxproj text eol=crlf encoding=UTF-8-BOM 8 | *.vcxproj.filters text eol=crlf encoding=UTF-8-BOM 9 | 10 | *.cs eol=lf diff=csharp 11 | 12 | *.doc diff=astextplain 13 | *.DOC diff=astextplain 14 | *.docx diff=astextplain 15 | *.DOCX diff=astextplain 16 | *.dot diff=astextplain 17 | *.DOT diff=astextplain 18 | *.pdf diff=astextplain 19 | *.PDF diff=astextplain 20 | *.rtf diff=astextplain 21 | *.RTF diff=astextplain 22 | 23 | *.ai binary 24 | *.bin binary 25 | *.bmp binary 26 | *.dat binary 27 | *.gif binary 28 | *.ico binary 29 | *.jpeg binary 30 | *.jpg binary 31 | *.otf binary 32 | *.png binary 33 | *.psd binary 34 | *.rc binary 35 | *.ttf binary 36 | *.woff binary 37 | *.woff2 binary 38 | *.xlsx binary 39 | 40 | vendor/* linguist-vendored 41 | external/* linguist-vendored 42 | subprojects/* linguist-vendored 43 | submodules/* linguist-vendored 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: marzer 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "gh-pages" 7 | paths: 8 | - "**.h" 9 | - "**.hpp" 10 | - "**.cpp" 11 | - "**.inl" 12 | - "**/meson.build" 13 | - "**/workflows/**.yaml" 14 | pull_request: 15 | branches-ignore: 16 | - "gh-pages" 17 | paths: 18 | - "**.h" 19 | - "**.hpp" 20 | - "**.cpp" 21 | - "**.inl" 22 | - "**/meson.build" 23 | - "**/workflows/**.yaml" 24 | workflow_dispatch: 25 | 26 | concurrency: 27 | group: ${{ github.workflow }}-${{ github.ref }} 28 | cancel-in-progress: true 29 | 30 | env: 31 | clang_version: "14" 32 | gcc_version: "11" 33 | 34 | jobs: 35 | linux: 36 | strategy: 37 | fail-fast: false 38 | matrix: 39 | compiler: 40 | - "clang" 41 | - "gcc" 42 | linker: 43 | - "lld" 44 | type: 45 | - "debug" 46 | - "release" 47 | 48 | runs-on: ubuntu-22.04 49 | 50 | defaults: 51 | run: 52 | shell: bash 53 | 54 | steps: 55 | - name: Install base dependencies 56 | run: | 57 | sudo apt -y update 58 | sudo apt -y install --no-install-recommends git python3 python3-pip ninja-build gettext libstdc++-${{ env.gcc_version }}-dev 59 | 60 | - name: Install lld 61 | if: ${{ startsWith(matrix.linker, 'lld') }} 62 | run: | 63 | sudo apt -y install --no-install-recommends lld-${{ env.clang_version }} 64 | sudo update-alternatives --install /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-${{ env.clang_version }} 1000 65 | 66 | - name: Install clang 67 | if: ${{ startsWith(matrix.compiler, 'clang') }} 68 | run: | 69 | sudo apt -y install --no-install-recommends clang-${{ env.clang_version }} 70 | sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-${{ env.clang_version }} 1000 71 | sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-${{ env.clang_version }} 1000 72 | 73 | - name: Install gcc 74 | if: ${{ startsWith(matrix.compiler, 'gcc') }} 75 | run: | 76 | sudo apt -y install --no-install-recommends gcc-${{ env.gcc_version }} g++-${{ env.gcc_version }} 77 | sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-${{ env.gcc_version }} 1000 78 | sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-${{ env.gcc_version }} 1000 79 | 80 | - uses: actions/checkout@v3 81 | 82 | - name: Install python dependencies 83 | run: | 84 | sudo -H pip3 install --no-cache-dir --upgrade meson 85 | 86 | - name: Configure Meson 87 | run: | 88 | CC=cc CC_LD=${{ matrix.linker }} CXX=c++ CXX_LD=${{ matrix.linker }} meson setup build --buildtype=${{ matrix.type }} -Dbuild_tests=true -Dbuild_examples=true 89 | 90 | - name: Build 91 | run: meson compile -C build 92 | 93 | - name: Test 94 | run: meson test -C build --verbose 95 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # documentation 35 | *.xml 36 | *.xslt 37 | *.xsd 38 | *.html 39 | *.temp 40 | docs/html/* 41 | docs/xml/* 42 | 43 | # visual studio 44 | .vs/ 45 | *.Designer.cs.dll 46 | *.VC.VC.opendb 47 | *.VC.db 48 | *.aps 49 | *.exp 50 | *.cachefile 51 | *.ilk 52 | *.iobj 53 | *.ipdb 54 | *.lastbuildstate 55 | *.log 56 | *.meta 57 | *.ncb 58 | *.obj 59 | *.opendb 60 | *.opensdf 61 | *.pch 62 | *.pdb 63 | *.pgc 64 | *.pgd 65 | *.pidb 66 | *.psess 67 | *.rsp 68 | *.sbr 69 | *.scc 70 | *.sdf 71 | *.sln.docstates 72 | *.suo 73 | *.svclog 74 | *.tlb 75 | *.tlh 76 | *.tli 77 | *.tlog 78 | *.tmp 79 | *.tmp_proj 80 | *.user 81 | *.userosscache 82 | *.vsidx 83 | *.vsp 84 | *.vspscc 85 | *.vspx 86 | *.vssscc 87 | *_i.c 88 | *_i.h 89 | *_p.c 90 | .builds 91 | ipch/ 92 | unsuccessfulbuild 93 | 94 | # meson 95 | meson-info/ 96 | meson-logs/ 97 | meson-private/ 98 | 99 | # Including strong name files can present a security risk 100 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 101 | *.snk 102 | 103 | # python 104 | __pycache__/ 105 | *.pyc 106 | 107 | # Windows 108 | Thumbs.db 109 | ehthumbs.db 110 | Desktop.ini 111 | $RECYCLE.BIN/ 112 | *.cab 113 | *.msi 114 | *.msm 115 | *.msp 116 | *.lnk 117 | 118 | # pitchfork 119 | build*/ 120 | _build*/ 121 | !build-aux/ 122 | 123 | # meson subprojects 124 | subprojects/*/ 125 | 126 | # sidle 127 | /sidledb.json 128 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.useTabs": true, 3 | "prettier.tabWidth": 4, 4 | "editor.rulers": [120], 5 | "editor.formatOnSave": true, 6 | "files.eol": "\n", 7 | "python.formatting.provider": "yapf", 8 | "html.format.indentInnerHtml": true, 9 | "files.exclude": { 10 | "**/__pycache__": true, 11 | "**/build": true, 12 | "**/*.egg-info": true 13 | }, 14 | "[cpp]": { 15 | "editor.formatOnSave": true 16 | }, 17 | "mesonbuild.configureOnOpen": false, 18 | "files.associations": { 19 | "bit": "cpp", 20 | "compare": "cpp", 21 | "concepts": "cpp", 22 | "cstddef": "cpp", 23 | "cstdint": "cpp", 24 | "cstdio": "cpp", 25 | "cstdlib": "cpp", 26 | "cwchar": "cpp", 27 | "initializer_list": "cpp", 28 | "limits": "cpp", 29 | "tuple": "cpp", 30 | "type_traits": "cpp", 31 | "utility": "cpp", 32 | "xstddef": "cpp", 33 | "xtr1common": "cpp" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Mark Gillard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `mz::type_list` [![MIT license](docs/images/badge-license-MIT.svg)](./LICENSE) [![C++17](docs/images/badge-c++17.svg)][cpp_compilers] [![Sponsor](docs/images/badge-sponsor.svg)][sponsor] [![Gitter](docs/images/badge-gitter.svg)][gitter] 2 | 3 | A variadic 'type list' for performing operations on lists of types in metaprogramming contexts. Optimized to be much more compiler-friendly than `std::tuple`. 4 | 5 | See [Compilation speed humps: std::tuple](https://marzer.github.io/md_blog_2021_05_31_compilation_speed_humps_std_tuple.html) for a write-up on the sorts of optimizations applied herein. 6 | 7 | Requires C++17. 8 | 9 |
10 | 11 | ## Synopsis 12 | 13 | ```cpp 14 | namespace mz 15 | { 16 | template 17 | struct type_list 18 | { 19 | // get the number of types in the list: 20 | static constexpr size_t length = sizeof...(T); 21 | 22 | // index of the first appearance of the specified type: 23 | template 24 | static constexpr size_t index_of = /* ... */; 25 | 26 | // determine if a specified type appears in the list: 27 | template 28 | static constexpr bool contains = /* ... */; 29 | 30 | // get a specific type: 31 | template 32 | using select = /* T...[Index] */; 33 | 34 | // convenience alias for select<0>: 35 | using first = select<0>; 36 | 37 | // convenience alias for select<0> when length == 1: 38 | using type = select<0>; 39 | 40 | // get a 'slice' (sublist): 41 | template 42 | using slice = type_list; 43 | 44 | // adding on to the beginning of the list: 45 | template 46 | using prepend = type_list; 47 | 48 | // adding on to the end of the list: 49 | template 50 | using append = type_list; 51 | 52 | // recursively flatten child sublists: 53 | using flatten = type_list; 54 | 55 | // remove all occurrences of the specified type: 56 | template 57 | using remove = type_list; 58 | }; 59 | 60 | // alias for a single-element list: 61 | template 62 | using type_tag = type_list; 63 | } 64 | ``` 65 | 66 |
67 | 68 | ## Usage 69 | 70 | The library is a single header so the easiest way to use it is to drop [type_list.hpp] somewhere in your project. 71 | 72 | Alternatively you can add `include` to your include paths then `#include ` 73 | 74 | There is also support for use as a `meson.build` subproject. 75 | 76 |
77 | 78 | ## Benchmarks 79 | 80 | Single-threaded compilation of the example application on my Ryzen 3950X: 81 | 82 | | | Clang 12 | GCC 10 | MSVC 19.29 | 83 | | -------------- | ------------ | ----------- | ----------- | 84 | | std::tuple | 6.448s | 3.185s | 7.965s | 85 | | mz::type_list | 0.303s | 0.407s | 0.830s | 86 | | speedup factor | 21.2x faster | 7.8x faster | 9.6x faster | 87 | 88 |
89 | 90 | ## License 91 | 92 | MIT. See [LICENSE](LICENSE). 93 | 94 |
95 | 96 | ## Contributing 97 | 98 | There are three ways you can contribute: 99 | 100 | 1. Reporting bug or making feature requests [here](https://github.com/marzer/type_list/issues/new) 101 | 2. Opening a pull request (⚠️ _caveat - see below_) 102 | 3. Becoming a [sponsor] ❤️ 103 | 104 | ### Pull requests 105 | 106 | `type_list.hpp` is programmatically extracted from a much larger project so I won't accept pull requests made for this repository directly; if you wish to contribute a bugfix or a feature, please find the type_list implementation [in this project](https://github.com/marzer/muu) and propose your changes there instead. I will then propagate them to this satellite library when they are merged. 107 | 108 | [type_list.hpp]: include/mz/type_list.hpp 109 | [license]: ./LICENSE 110 | [cpp_compilers]: https://en.cppreference.com/w/cpp/compiler_support 111 | [gitter]: https://gitter.im/marzer/community 112 | [sponsor]: https://github.com/sponsors/marzer 113 | -------------------------------------------------------------------------------- /docs/images/badge-c++17.svg: -------------------------------------------------------------------------------- 1 | standardC++17 -------------------------------------------------------------------------------- /docs/images/badge-gitter.svg: -------------------------------------------------------------------------------- 1 | chat: on gitterchaton gitter -------------------------------------------------------------------------------- /docs/images/badge-license-MIT.svg: -------------------------------------------------------------------------------- 1 | licenseMIT -------------------------------------------------------------------------------- /docs/images/badge-sponsor.svg: -------------------------------------------------------------------------------- 1 | sponsor: ❤sponsor -------------------------------------------------------------------------------- /examples/comparison_adapter_std_tuple.hpp: -------------------------------------------------------------------------------- 1 | // This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace mz 10 | { 11 | using std::size_t; 12 | 13 | template 14 | using type_list = std::tuple; 15 | 16 | template 17 | using type_list_select = typename std::tuple_element::type; 18 | 19 | namespace impl 20 | { 21 | template 22 | struct type_list_slicer_; 23 | 24 | template 25 | struct type_list_slicer_> 26 | { 27 | using type = type_list...>; 28 | }; 29 | } 30 | 31 | template 32 | using type_list_slice = typename impl::type_list_slicer_>::type; 33 | 34 | template 35 | inline constexpr size_t type_list_length = std::tuple_size_v; 36 | } 37 | -------------------------------------------------------------------------------- /examples/comparison_adapter_type_list.hpp: -------------------------------------------------------------------------------- 1 | // This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace mz 10 | { 11 | template 12 | using type_list_select = typename List::template select; 13 | 14 | template 15 | using type_list_slice = typename List::template slice; 16 | 17 | template 18 | inline constexpr size_t type_list_length = List::length; 19 | } 20 | -------------------------------------------------------------------------------- /examples/comparison_adapters.hpp: -------------------------------------------------------------------------------- 1 | // This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | #pragma once 6 | 7 | #ifndef USE_STD_TUPLE 8 | #define USE_STD_TUPLE 0 9 | #endif 10 | #if USE_STD_TUPLE 11 | #include "comparison_adapter_std_tuple.hpp" 12 | #else 13 | #include "comparison_adapter_type_list.hpp" 14 | #endif 15 | #include 16 | 17 | namespace mz 18 | { 19 | template 20 | using index_tag = std::integral_constant; 21 | 22 | namespace impl 23 | { 24 | template 25 | struct type_list_maker_; 26 | 27 | template 28 | struct type_list_maker_> 29 | { 30 | using type = type_list...>; 31 | }; 32 | } 33 | 34 | template 35 | using make_type_list = typename impl::type_list_maker_>::type; 36 | } 37 | -------------------------------------------------------------------------------- /examples/comparison_main.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | // 6 | // this was the test code used in the 'Compilation speed humps: std::tuple' write-up 7 | // (https://marzer.github.io/md_blog_2021_05_31_compilation_speed_humps_std_tuple.html) 8 | 9 | #include 10 | #include 11 | #include "comparison_adapters.hpp" 12 | 13 | namespace mz 14 | { 15 | namespace impl 16 | { 17 | template 18 | constexpr void for_sequence_(Func&& func, std::integer_sequence) 19 | { 20 | (static_cast(static_cast(func)(std::integral_constant{})), ...); 21 | } 22 | } 23 | 24 | template 25 | constexpr void for_sequence(Func&& func) 26 | { 27 | using n_type = decltype(N); 28 | static_assert(N >= n_type{}, "N cannot be negative."); 29 | 30 | if constexpr (N > n_type{}) 31 | impl::for_sequence_(static_cast(func), std::make_integer_sequence{}); 32 | else 33 | static_cast(func); 34 | } 35 | 36 | template 37 | [[maybe_unused]] static void consume_type_list() noexcept 38 | { 39 | std::printf("%zu\n", type_list_length); 40 | } 41 | } 42 | 43 | using namespace mz; 44 | 45 | int main() 46 | { 47 | // do some arbitrary nonsense with big type_lists (extremely RAM intensive!) 48 | #if 0 49 | { 50 | using list_1 = make_type_list<0, 1000>; 51 | using list_2 = type_list_slice; 52 | using list_3 = type_list_slice; 53 | using list_4 = type_list_slice; 54 | 55 | consume_type_list(); 56 | consume_type_list(); 57 | consume_type_list(); 58 | consume_type_list(); 59 | 60 | using type_1 = type_list_select; 61 | using type_2 = type_list_select; 62 | using type_3 = type_list_select; 63 | using type_4 = type_list_select; 64 | 65 | using list_5 = type_list; 66 | 67 | consume_type_list(); 68 | } 69 | 70 | #endif 71 | 72 | // simulating my original CI project structure 73 | #if 1 74 | { 75 | using types = make_type_list<0, 200>; 76 | 77 | constexpr size_t slice_length = type_list_length / 10u; 78 | constexpr size_t slice_count = type_list_length / slice_length // 79 | + (type_list_length % slice_length ? 1u : 0u); 80 | 81 | for_sequence( 82 | [](auto sidx) 83 | { 84 | constexpr size_t slice_index = decltype(sidx)::value; 85 | constexpr size_t slice_start = slice_index * slice_length; 86 | constexpr size_t slice_end = type_list_length < slice_start + slice_length 87 | ? type_list_length 88 | : slice_start + slice_length; 89 | 90 | using slice = type_list_slice; 91 | for_sequence>([](auto idx) { std::printf("%zu\n", decltype(idx)::value); }); 92 | }); 93 | } 94 | #endif 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /examples/meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | cpp = meson.get_compiler('cpp') 7 | 8 | example_args = [] 9 | example_args += cpp.first_supported_argument('-ftime-trace') 10 | 11 | example_overrides = [] 12 | example_overrides = [ 'warning_level=0' ] 13 | 14 | executable( 15 | 'comparsion_type_list', 16 | [ 'comparison_main.cpp' ], 17 | cpp_args : example_args + [ '-DUSE_STD_TUPLE=0' ], 18 | override_options: example_overrides, 19 | dependencies: [ type_list_dep ], 20 | install: false 21 | ) 22 | 23 | executable( 24 | 'comparsion_tuple', 25 | [ 'comparison_main.cpp' ], 26 | cpp_args : example_args + [ '-DUSE_STD_TUPLE=1' ], 27 | override_options: example_overrides, 28 | dependencies: [ type_list_dep ], 29 | install: false 30 | ) 31 | -------------------------------------------------------------------------------- /include/meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | include_dir = include_directories('.') 7 | 8 | if not meson.is_subproject() 9 | install_subdir('mz', install_dir: get_option('includedir')) 10 | endif 11 | -------------------------------------------------------------------------------- /include/mz/type_list.hpp: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // mz::type_list 4 | // https://github.com/marzer/type_list 5 | // SPDX-License-Identifier: MIT 6 | // 7 | //---------------------------------------------------------------------------------------------------------------------- 8 | // THIS FILE WAS ASSEMBLED FROM MULTIPLE HEADER FILES BY A SCRIPT - PLEASE DON'T EDIT IT DIRECTLY 9 | //---------------------------------------------------------------------------------------------------------------------- 10 | // 11 | // MIT License 12 | // 13 | // Copyright (c) Mark Gillard 14 | // 15 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 16 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 17 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 18 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 21 | // the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 24 | // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 27 | // SOFTWARE. 28 | // 29 | //---------------------------------------------------------------------------------------------------------------------- 30 | #ifndef MZ_TYPE_LIST_HPP 31 | #define MZ_TYPE_LIST_HPP 32 | 33 | #define MZ_TYPE_LIST_VERSION_MAJOR 1 34 | #define MZ_TYPE_LIST_VERSION_MINOR 0 35 | #define MZ_TYPE_LIST_VERSION_PATCH 0 36 | 37 | #ifndef MZ_MAKE_VERSION 38 | #define MZ_MAKE_VERSION(major, minor, patch) (((major)*10000) + ((minor)*100) + ((patch))) 39 | #endif 40 | 41 | #ifndef MZ_CLANG 42 | #ifdef __clang__ 43 | #define MZ_CLANG __clang_major__ 44 | #else 45 | #define MZ_CLANG 0 46 | #endif 47 | 48 | // special handling for apple clang; see: 49 | // - https://github.com/marzer/tomlplusplus/issues/189 50 | // - https://en.wikipedia.org/wiki/Xcode 51 | // - 52 | // https://stackoverflow.com/questions/19387043/how-can-i-reliably-detect-the-version-of-clang-at-preprocessing-time 53 | #if MZ_CLANG && defined(__apple_build_version__) 54 | #undef MZ_CLANG 55 | #define MZ_CLANG_VERSION MZ_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) 56 | #if MZ_CLANG_VERSION >= MZ_MAKE_VERSION(15, 0, 0) 57 | #define MZ_CLANG 16 58 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(14, 3, 0) 59 | #define MZ_CLANG 15 60 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(14, 0, 0) 61 | #define MZ_CLANG 14 62 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(13, 1, 6) 63 | #define MZ_CLANG 13 64 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(13, 0, 0) 65 | #define MZ_CLANG 12 66 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(12, 0, 5) 67 | #define MZ_CLANG 11 68 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(12, 0, 0) 69 | #define MZ_CLANG 10 70 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(11, 0, 3) 71 | #define MZ_CLANG 9 72 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(11, 0, 0) 73 | #define MZ_CLANG 8 74 | #elif MZ_CLANG_VERSION >= MZ_MAKE_VERSION(10, 0, 1) 75 | #define MZ_CLANG 7 76 | #else 77 | #define MZ_CLANG 6 // not strictly correct but doesn't matter below this 78 | #endif 79 | #undef MZ_CLANG_VERSION 80 | #endif 81 | #endif 82 | 83 | #ifndef MZ_MSVC_LIKE 84 | #ifdef _MSC_VER 85 | #define MZ_MSVC_LIKE _MSC_VER 86 | #else 87 | #define MZ_MSVC_LIKE 0 88 | #endif 89 | #endif 90 | 91 | #ifndef MZ_CONCAT 92 | #define MZ_CONCAT_2(x, y) x##y 93 | #define MZ_CONCAT_1(x, y) MZ_CONCAT_2(x, y) 94 | #define MZ_CONCAT(x, y) MZ_CONCAT_1(x, y) 95 | #endif 96 | 97 | #ifndef MZ_HAS_BUILTIN 98 | #ifdef __has_builtin 99 | #define MZ_HAS_BUILTIN(name) __has_builtin(name) 100 | #else 101 | #define MZ_HAS_BUILTIN(name) 0 102 | #endif 103 | #endif 104 | 105 | #ifndef MZ_FOR_EACH 106 | 107 | #define MZ_FOR_EACH_FORCE_UNROLL(x) x // without this msvc treats forwarded __VA_ARGS__ as a single token 108 | 109 | #define MZ_FOR_EACH_IMPL_0(fn, x) fn(x) 110 | #define MZ_FOR_EACH_IMPL_1(fn, x, ...) fn(x) MZ_FOR_EACH_IMPL_0(fn, __VA_ARGS__) 111 | #define MZ_FOR_EACH_IMPL_2(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_1(fn, __VA_ARGS__)) 112 | #define MZ_FOR_EACH_IMPL_3(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_2(fn, __VA_ARGS__)) 113 | #define MZ_FOR_EACH_IMPL_4(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_3(fn, __VA_ARGS__)) 114 | #define MZ_FOR_EACH_IMPL_5(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_4(fn, __VA_ARGS__)) 115 | #define MZ_FOR_EACH_IMPL_6(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_5(fn, __VA_ARGS__)) 116 | #define MZ_FOR_EACH_IMPL_7(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_6(fn, __VA_ARGS__)) 117 | #define MZ_FOR_EACH_IMPL_8(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_7(fn, __VA_ARGS__)) 118 | #define MZ_FOR_EACH_IMPL_9(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_8(fn, __VA_ARGS__)) 119 | #define MZ_FOR_EACH_IMPL_10(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_9(fn, __VA_ARGS__)) 120 | #define MZ_FOR_EACH_IMPL_11(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_10(fn, __VA_ARGS__)) 121 | #define MZ_FOR_EACH_IMPL_12(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_11(fn, __VA_ARGS__)) 122 | #define MZ_FOR_EACH_IMPL_13(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_12(fn, __VA_ARGS__)) 123 | #define MZ_FOR_EACH_IMPL_14(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_13(fn, __VA_ARGS__)) 124 | #define MZ_FOR_EACH_IMPL_15(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_14(fn, __VA_ARGS__)) 125 | #define MZ_FOR_EACH_IMPL_16(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_15(fn, __VA_ARGS__)) 126 | #define MZ_FOR_EACH_IMPL_17(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_16(fn, __VA_ARGS__)) 127 | #define MZ_FOR_EACH_IMPL_18(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_17(fn, __VA_ARGS__)) 128 | #define MZ_FOR_EACH_IMPL_19(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_18(fn, __VA_ARGS__)) 129 | #define MZ_FOR_EACH_IMPL_20(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_19(fn, __VA_ARGS__)) 130 | #define MZ_FOR_EACH_IMPL_21(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_20(fn, __VA_ARGS__)) 131 | #define MZ_FOR_EACH_IMPL_22(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_21(fn, __VA_ARGS__)) 132 | #define MZ_FOR_EACH_IMPL_23(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_22(fn, __VA_ARGS__)) 133 | #define MZ_FOR_EACH_IMPL_24(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_23(fn, __VA_ARGS__)) 134 | #define MZ_FOR_EACH_IMPL_25(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_24(fn, __VA_ARGS__)) 135 | #define MZ_FOR_EACH_IMPL_26(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_25(fn, __VA_ARGS__)) 136 | #define MZ_FOR_EACH_IMPL_27(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_26(fn, __VA_ARGS__)) 137 | #define MZ_FOR_EACH_IMPL_28(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_27(fn, __VA_ARGS__)) 138 | #define MZ_FOR_EACH_IMPL_29(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_28(fn, __VA_ARGS__)) 139 | #define MZ_FOR_EACH_IMPL_30(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_29(fn, __VA_ARGS__)) 140 | #define MZ_FOR_EACH_IMPL_31(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_30(fn, __VA_ARGS__)) 141 | #define MZ_FOR_EACH_IMPL_32(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_31(fn, __VA_ARGS__)) 142 | #define MZ_FOR_EACH_IMPL_33(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_32(fn, __VA_ARGS__)) 143 | #define MZ_FOR_EACH_IMPL_34(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_33(fn, __VA_ARGS__)) 144 | #define MZ_FOR_EACH_IMPL_35(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_34(fn, __VA_ARGS__)) 145 | #define MZ_FOR_EACH_IMPL_36(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_35(fn, __VA_ARGS__)) 146 | #define MZ_FOR_EACH_IMPL_37(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_36(fn, __VA_ARGS__)) 147 | #define MZ_FOR_EACH_IMPL_38(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_37(fn, __VA_ARGS__)) 148 | #define MZ_FOR_EACH_IMPL_39(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_38(fn, __VA_ARGS__)) 149 | #define MZ_FOR_EACH_IMPL_40(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_39(fn, __VA_ARGS__)) 150 | #define MZ_FOR_EACH_IMPL_41(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_40(fn, __VA_ARGS__)) 151 | #define MZ_FOR_EACH_IMPL_42(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_41(fn, __VA_ARGS__)) 152 | #define MZ_FOR_EACH_IMPL_43(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_42(fn, __VA_ARGS__)) 153 | #define MZ_FOR_EACH_IMPL_44(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_43(fn, __VA_ARGS__)) 154 | #define MZ_FOR_EACH_IMPL_45(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_44(fn, __VA_ARGS__)) 155 | #define MZ_FOR_EACH_IMPL_46(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_45(fn, __VA_ARGS__)) 156 | #define MZ_FOR_EACH_IMPL_47(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_46(fn, __VA_ARGS__)) 157 | #define MZ_FOR_EACH_IMPL_48(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_47(fn, __VA_ARGS__)) 158 | #define MZ_FOR_EACH_IMPL_49(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_48(fn, __VA_ARGS__)) 159 | #define MZ_FOR_EACH_IMPL_50(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_49(fn, __VA_ARGS__)) 160 | #define MZ_FOR_EACH_IMPL_51(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_50(fn, __VA_ARGS__)) 161 | #define MZ_FOR_EACH_IMPL_52(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_51(fn, __VA_ARGS__)) 162 | #define MZ_FOR_EACH_IMPL_53(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_52(fn, __VA_ARGS__)) 163 | #define MZ_FOR_EACH_IMPL_54(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_53(fn, __VA_ARGS__)) 164 | #define MZ_FOR_EACH_IMPL_55(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_54(fn, __VA_ARGS__)) 165 | #define MZ_FOR_EACH_IMPL_56(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_55(fn, __VA_ARGS__)) 166 | #define MZ_FOR_EACH_IMPL_57(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_56(fn, __VA_ARGS__)) 167 | #define MZ_FOR_EACH_IMPL_58(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_57(fn, __VA_ARGS__)) 168 | #define MZ_FOR_EACH_IMPL_59(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_58(fn, __VA_ARGS__)) 169 | #define MZ_FOR_EACH_IMPL_60(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_59(fn, __VA_ARGS__)) 170 | #define MZ_FOR_EACH_IMPL_61(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_60(fn, __VA_ARGS__)) 171 | #define MZ_FOR_EACH_IMPL_62(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_61(fn, __VA_ARGS__)) 172 | #define MZ_FOR_EACH_IMPL_63(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_62(fn, __VA_ARGS__)) 173 | #define MZ_FOR_EACH_IMPL_64(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_63(fn, __VA_ARGS__)) 174 | #define MZ_FOR_EACH_IMPL_65(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_64(fn, __VA_ARGS__)) 175 | #define MZ_FOR_EACH_IMPL_66(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_65(fn, __VA_ARGS__)) 176 | #define MZ_FOR_EACH_IMPL_67(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_66(fn, __VA_ARGS__)) 177 | #define MZ_FOR_EACH_IMPL_68(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_67(fn, __VA_ARGS__)) 178 | #define MZ_FOR_EACH_IMPL_69(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_68(fn, __VA_ARGS__)) 179 | #define MZ_FOR_EACH_IMPL_70(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_69(fn, __VA_ARGS__)) 180 | #define MZ_FOR_EACH_IMPL_71(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_70(fn, __VA_ARGS__)) 181 | #define MZ_FOR_EACH_IMPL_72(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_71(fn, __VA_ARGS__)) 182 | #define MZ_FOR_EACH_IMPL_73(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_72(fn, __VA_ARGS__)) 183 | #define MZ_FOR_EACH_IMPL_74(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_73(fn, __VA_ARGS__)) 184 | #define MZ_FOR_EACH_IMPL_75(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_74(fn, __VA_ARGS__)) 185 | #define MZ_FOR_EACH_IMPL_76(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_75(fn, __VA_ARGS__)) 186 | #define MZ_FOR_EACH_IMPL_77(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_76(fn, __VA_ARGS__)) 187 | #define MZ_FOR_EACH_IMPL_78(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_77(fn, __VA_ARGS__)) 188 | #define MZ_FOR_EACH_IMPL_79(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_78(fn, __VA_ARGS__)) 189 | #define MZ_FOR_EACH_IMPL_80(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_79(fn, __VA_ARGS__)) 190 | #define MZ_FOR_EACH_IMPL_81(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_80(fn, __VA_ARGS__)) 191 | #define MZ_FOR_EACH_IMPL_82(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_81(fn, __VA_ARGS__)) 192 | #define MZ_FOR_EACH_IMPL_83(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_82(fn, __VA_ARGS__)) 193 | #define MZ_FOR_EACH_IMPL_84(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_83(fn, __VA_ARGS__)) 194 | #define MZ_FOR_EACH_IMPL_85(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_84(fn, __VA_ARGS__)) 195 | #define MZ_FOR_EACH_IMPL_86(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_85(fn, __VA_ARGS__)) 196 | #define MZ_FOR_EACH_IMPL_87(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_86(fn, __VA_ARGS__)) 197 | #define MZ_FOR_EACH_IMPL_88(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_87(fn, __VA_ARGS__)) 198 | #define MZ_FOR_EACH_IMPL_89(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_88(fn, __VA_ARGS__)) 199 | #define MZ_FOR_EACH_IMPL_90(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_89(fn, __VA_ARGS__)) 200 | #define MZ_FOR_EACH_IMPL_91(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_90(fn, __VA_ARGS__)) 201 | #define MZ_FOR_EACH_IMPL_92(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_91(fn, __VA_ARGS__)) 202 | #define MZ_FOR_EACH_IMPL_93(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_92(fn, __VA_ARGS__)) 203 | #define MZ_FOR_EACH_IMPL_94(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_93(fn, __VA_ARGS__)) 204 | #define MZ_FOR_EACH_IMPL_95(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_94(fn, __VA_ARGS__)) 205 | #define MZ_FOR_EACH_IMPL_96(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_95(fn, __VA_ARGS__)) 206 | #define MZ_FOR_EACH_IMPL_97(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_96(fn, __VA_ARGS__)) 207 | #define MZ_FOR_EACH_IMPL_98(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_97(fn, __VA_ARGS__)) 208 | #define MZ_FOR_EACH_IMPL_99(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_98(fn, __VA_ARGS__)) 209 | #define MZ_FOR_EACH_IMPL_100(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_99(fn, __VA_ARGS__)) 210 | #define MZ_FOR_EACH_IMPL_101(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_100(fn, __VA_ARGS__)) 211 | #define MZ_FOR_EACH_IMPL_102(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_101(fn, __VA_ARGS__)) 212 | #define MZ_FOR_EACH_IMPL_103(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_102(fn, __VA_ARGS__)) 213 | #define MZ_FOR_EACH_IMPL_104(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_103(fn, __VA_ARGS__)) 214 | #define MZ_FOR_EACH_IMPL_105(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_104(fn, __VA_ARGS__)) 215 | #define MZ_FOR_EACH_IMPL_106(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_105(fn, __VA_ARGS__)) 216 | #define MZ_FOR_EACH_IMPL_107(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_106(fn, __VA_ARGS__)) 217 | #define MZ_FOR_EACH_IMPL_108(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_107(fn, __VA_ARGS__)) 218 | #define MZ_FOR_EACH_IMPL_109(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_108(fn, __VA_ARGS__)) 219 | #define MZ_FOR_EACH_IMPL_110(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_109(fn, __VA_ARGS__)) 220 | #define MZ_FOR_EACH_IMPL_111(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_110(fn, __VA_ARGS__)) 221 | #define MZ_FOR_EACH_IMPL_112(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_111(fn, __VA_ARGS__)) 222 | #define MZ_FOR_EACH_IMPL_113(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_112(fn, __VA_ARGS__)) 223 | #define MZ_FOR_EACH_IMPL_114(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_113(fn, __VA_ARGS__)) 224 | #define MZ_FOR_EACH_IMPL_115(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_114(fn, __VA_ARGS__)) 225 | #define MZ_FOR_EACH_IMPL_116(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_115(fn, __VA_ARGS__)) 226 | #define MZ_FOR_EACH_IMPL_117(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_116(fn, __VA_ARGS__)) 227 | #define MZ_FOR_EACH_IMPL_118(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_117(fn, __VA_ARGS__)) 228 | #define MZ_FOR_EACH_IMPL_119(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_118(fn, __VA_ARGS__)) 229 | #define MZ_FOR_EACH_IMPL_120(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_119(fn, __VA_ARGS__)) 230 | #define MZ_FOR_EACH_IMPL_121(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_120(fn, __VA_ARGS__)) 231 | #define MZ_FOR_EACH_IMPL_122(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_121(fn, __VA_ARGS__)) 232 | #define MZ_FOR_EACH_IMPL_123(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_122(fn, __VA_ARGS__)) 233 | #define MZ_FOR_EACH_IMPL_124(fn, x, ...) fn(x) MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_123(fn, __VA_ARGS__)) 234 | 235 | // clang-format off 236 | 237 | #define MZ_FOR_EACH_IMPL_SELECT(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, \ 238 | _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, \ 239 | _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \ 240 | _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, \ 241 | _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, _101, _102, \ 242 | _103, _104, _105, _106, _107, _108, _109, _110, _111, _112, _113, _114, _115, _116, _117, _118, _119, _120, \ 243 | _121, _122, _123, _124, fn, ...) \ 244 | fn 245 | 246 | #define MZ_FOR_EACH(fn, ...) \ 247 | MZ_FOR_EACH_FORCE_UNROLL(MZ_FOR_EACH_IMPL_SELECT(__VA_ARGS__, MZ_FOR_EACH_IMPL_124, MZ_FOR_EACH_IMPL_123, \ 248 | MZ_FOR_EACH_IMPL_122, MZ_FOR_EACH_IMPL_121, MZ_FOR_EACH_IMPL_120, MZ_FOR_EACH_IMPL_119, \ 249 | MZ_FOR_EACH_IMPL_118, MZ_FOR_EACH_IMPL_117, MZ_FOR_EACH_IMPL_116, MZ_FOR_EACH_IMPL_115, \ 250 | MZ_FOR_EACH_IMPL_114, MZ_FOR_EACH_IMPL_113, MZ_FOR_EACH_IMPL_112, MZ_FOR_EACH_IMPL_111, \ 251 | MZ_FOR_EACH_IMPL_110, MZ_FOR_EACH_IMPL_109, MZ_FOR_EACH_IMPL_108, MZ_FOR_EACH_IMPL_107, \ 252 | MZ_FOR_EACH_IMPL_106, MZ_FOR_EACH_IMPL_105, MZ_FOR_EACH_IMPL_104, MZ_FOR_EACH_IMPL_103, \ 253 | MZ_FOR_EACH_IMPL_102, MZ_FOR_EACH_IMPL_101, MZ_FOR_EACH_IMPL_100, MZ_FOR_EACH_IMPL_99, \ 254 | MZ_FOR_EACH_IMPL_98, MZ_FOR_EACH_IMPL_97, MZ_FOR_EACH_IMPL_96, MZ_FOR_EACH_IMPL_95, MZ_FOR_EACH_IMPL_94, \ 255 | MZ_FOR_EACH_IMPL_93, MZ_FOR_EACH_IMPL_92, MZ_FOR_EACH_IMPL_91, MZ_FOR_EACH_IMPL_90, MZ_FOR_EACH_IMPL_89, \ 256 | MZ_FOR_EACH_IMPL_88, MZ_FOR_EACH_IMPL_87, MZ_FOR_EACH_IMPL_86, MZ_FOR_EACH_IMPL_85, MZ_FOR_EACH_IMPL_84, \ 257 | MZ_FOR_EACH_IMPL_83, MZ_FOR_EACH_IMPL_82, MZ_FOR_EACH_IMPL_81, MZ_FOR_EACH_IMPL_80, MZ_FOR_EACH_IMPL_79, \ 258 | MZ_FOR_EACH_IMPL_78, MZ_FOR_EACH_IMPL_77, MZ_FOR_EACH_IMPL_76, MZ_FOR_EACH_IMPL_75, MZ_FOR_EACH_IMPL_74, \ 259 | MZ_FOR_EACH_IMPL_73, MZ_FOR_EACH_IMPL_72, MZ_FOR_EACH_IMPL_71, MZ_FOR_EACH_IMPL_70, MZ_FOR_EACH_IMPL_69, \ 260 | MZ_FOR_EACH_IMPL_68, MZ_FOR_EACH_IMPL_67, MZ_FOR_EACH_IMPL_66, MZ_FOR_EACH_IMPL_65, MZ_FOR_EACH_IMPL_64, \ 261 | MZ_FOR_EACH_IMPL_63, MZ_FOR_EACH_IMPL_62, MZ_FOR_EACH_IMPL_61, MZ_FOR_EACH_IMPL_60, MZ_FOR_EACH_IMPL_59, \ 262 | MZ_FOR_EACH_IMPL_58, MZ_FOR_EACH_IMPL_57, MZ_FOR_EACH_IMPL_56, MZ_FOR_EACH_IMPL_55, MZ_FOR_EACH_IMPL_54, \ 263 | MZ_FOR_EACH_IMPL_53, MZ_FOR_EACH_IMPL_52, MZ_FOR_EACH_IMPL_51, MZ_FOR_EACH_IMPL_50, MZ_FOR_EACH_IMPL_49, \ 264 | MZ_FOR_EACH_IMPL_48, MZ_FOR_EACH_IMPL_47, MZ_FOR_EACH_IMPL_46, MZ_FOR_EACH_IMPL_45, MZ_FOR_EACH_IMPL_44, \ 265 | MZ_FOR_EACH_IMPL_43, MZ_FOR_EACH_IMPL_42, MZ_FOR_EACH_IMPL_41, MZ_FOR_EACH_IMPL_40, MZ_FOR_EACH_IMPL_39, \ 266 | MZ_FOR_EACH_IMPL_38, MZ_FOR_EACH_IMPL_37, MZ_FOR_EACH_IMPL_36, MZ_FOR_EACH_IMPL_35, MZ_FOR_EACH_IMPL_34, \ 267 | MZ_FOR_EACH_IMPL_33, MZ_FOR_EACH_IMPL_32, MZ_FOR_EACH_IMPL_31, MZ_FOR_EACH_IMPL_30, MZ_FOR_EACH_IMPL_29, \ 268 | MZ_FOR_EACH_IMPL_28, MZ_FOR_EACH_IMPL_27, MZ_FOR_EACH_IMPL_26, MZ_FOR_EACH_IMPL_25, MZ_FOR_EACH_IMPL_24, \ 269 | MZ_FOR_EACH_IMPL_23, MZ_FOR_EACH_IMPL_22, MZ_FOR_EACH_IMPL_21, MZ_FOR_EACH_IMPL_20, MZ_FOR_EACH_IMPL_19, \ 270 | MZ_FOR_EACH_IMPL_18, MZ_FOR_EACH_IMPL_17, MZ_FOR_EACH_IMPL_16, MZ_FOR_EACH_IMPL_15, MZ_FOR_EACH_IMPL_14, \ 271 | MZ_FOR_EACH_IMPL_13, MZ_FOR_EACH_IMPL_12, MZ_FOR_EACH_IMPL_11, MZ_FOR_EACH_IMPL_10, MZ_FOR_EACH_IMPL_9, \ 272 | MZ_FOR_EACH_IMPL_8, MZ_FOR_EACH_IMPL_7, MZ_FOR_EACH_IMPL_6, MZ_FOR_EACH_IMPL_5, MZ_FOR_EACH_IMPL_4, \ 273 | MZ_FOR_EACH_IMPL_3, MZ_FOR_EACH_IMPL_2, MZ_FOR_EACH_IMPL_1, MZ_FOR_EACH_IMPL_0)(fn, __VA_ARGS__)) 274 | 275 | // clang-format on 276 | 277 | #endif // MZ_FOR_EACH 278 | 279 | #ifndef MZ_COUNT_VA_ARGS 280 | 281 | // clang-format off 282 | 283 | #define MZ_COUNT_VA_ARGS_IMPL(_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, \ 284 | _16_, _17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, _33_, \ 285 | _34_, _35_, _36_, _37_, _38_, _39_, _40_, _41_, _42_, _43_, _44_, _45_, _46_, _47_, _48_, _49_, _50_, _51_, \ 286 | _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, _65_, _66_, _67_, _68_, _69_, \ 287 | _70_, _71_, _72_, _73_, _74_, _75_, _76_, _77_, _78_, _79_, _80_, _81_, _82_, _83_, _84_, _85_, _86_, _87_, \ 288 | _88_, _89_, _90_, _91_, _92_, _93_, _94_, _95_, _96_, _97_, _98_, _99_, _100_, _101_, _102_, _103_, _104_, \ 289 | _105_, _106_, _107_, _108_, _109_, _110_, _111_, _112_, _113_, _114_, _115_, _116_, _117_, _118_, _119_, _120_,\ 290 | _121_, _122_, _123_, _124_, count, ...) count 291 | 292 | #define MZ_COUNT_VA_ARGS_IMPL_EXPANDER(args) MZ_COUNT_VA_ARGS_IMPL args 293 | 294 | #define MZ_COUNT_VA_ARGS(...) MZ_COUNT_VA_ARGS_IMPL_EXPANDER((__VA_ARGS__, 124, 123, 122, 121, 120, 119, 118, \ 295 | 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, \ 296 | 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67,\ 297 | 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39,\ 298 | 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11,\ 299 | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) 300 | 301 | // clang-format on 302 | 303 | #endif // MZ_COUNT_VA_ARGS 304 | 305 | #ifndef MZ_COMMA 306 | #define MZ_COMMA , 307 | #endif 308 | 309 | #ifndef MZ_DECLSPEC 310 | #if MZ_MSVC_LIKE 311 | #define MZ_DECLSPEC(...) __declspec(__VA_ARGS__) 312 | #else 313 | #define MZ_DECLSPEC(...) 314 | #endif 315 | #endif 316 | 317 | #ifndef MZ_EMPTY_BASES 318 | #if MZ_MSVC_LIKE 319 | #define MZ_EMPTY_BASES MZ_DECLSPEC(empty_bases) 320 | #else 321 | #define MZ_EMPTY_BASES 322 | #endif 323 | #endif 324 | 325 | #ifndef MZ_TYPE_LIST_PAGE_SIZE 326 | #undef MZ_TYPE_LIST_PAGE_SIZE 327 | #define MZ_TYPE_LIST_PAGE_SIZE 32 328 | #endif 329 | #if MZ_TYPE_LIST_PAGE_SIZE < 8 330 | #undef MZ_TYPE_LIST_PAGE_SIZE 331 | #define MZ_TYPE_LIST_PAGE_SIZE 8 332 | #endif 333 | #if MZ_TYPE_LIST_PAGE_SIZE > 64 334 | #undef MZ_TYPE_LIST_PAGE_SIZE 335 | #define MZ_TYPE_LIST_PAGE_SIZE 64 336 | #endif 337 | #if !(MZ_TYPE_LIST_PAGE_SIZE == 8 || MZ_TYPE_LIST_PAGE_SIZE == 16 || MZ_TYPE_LIST_PAGE_SIZE == 32 \ 338 | || MZ_TYPE_LIST_PAGE_SIZE == 48 || MZ_TYPE_LIST_PAGE_SIZE == 64) 339 | #error MZ_TYPE_LIST_PAGE_SIZE must be 8, 16, 32, 48 or 64. 340 | #endif 341 | 342 | #ifndef MZ_TYPE_LIST_HAS_JUMBO_PAGES 343 | #define MZ_TYPE_LIST_HAS_JUMBO_PAGES 1 344 | #endif 345 | 346 | #if MZ_HAS_BUILTIN(__type_pack_element) || MZ_CLANG >= 6 // older clang implemented __has_builtin poorly 347 | #define MZ_HAS_TYPE_PACK_ELEMENT 1 348 | #else 349 | #define MZ_HAS_TYPE_PACK_ELEMENT 0 350 | #endif 351 | 352 | #ifndef MZ_HAS_INTEGER_SEQ 353 | #if MZ_CLANG || MZ_MSVC_LIKE 354 | #define MZ_HAS_INTEGER_SEQ 1 355 | #else 356 | #define MZ_HAS_INTEGER_SEQ 0 357 | #endif 358 | #endif 359 | #if !MZ_HAS_INTEGER_SEQ 360 | #include 361 | #endif 362 | 363 | #define MZ_MAKE_INDEXED_TPARAM(N) MZ_COMMA typename MZ_CONCAT(T, N) 364 | #define MZ_MAKE_INDEXED_TARG(N) MZ_COMMA MZ_CONCAT(T, N) 365 | #define MZ_0_TO_7 0, 1, 2, 3, 4, 5, 6, 7 366 | #define MZ_0_TO_15 MZ_0_TO_7, 8, 9, 10, 11, 12, 13, 14, 15 367 | #define MZ_0_TO_31 MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 368 | #define MZ_0_TO_47 MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 369 | #define MZ_0_TO_63 MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63 370 | 371 | #include 372 | #include 373 | 374 | namespace mz 375 | { 376 | using std::size_t; 377 | 378 | #if 1 379 | 380 | #ifndef MZ_HAS_SNIPPET_META_ALWAYS_FALSE 381 | #define MZ_HAS_SNIPPET_META_ALWAYS_FALSE 382 | 383 | template 384 | inline constexpr bool always_false = false; 385 | 386 | #endif // MZ_HAS_SNIPPET_META_ALWAYS_FALSE 387 | 388 | #ifndef MZ_HAS_SNIPPET_META_INDEX_OF_TYPE 389 | #define MZ_HAS_SNIPPET_META_INDEX_OF_TYPE 390 | 391 | namespace detail 392 | { 393 | template 394 | struct index_of_type_ 395 | { 396 | static_assert(always_false, "type not found in list"); 397 | }; 398 | 399 | template 400 | struct index_of_type_ 401 | { 402 | static constexpr size_t value = I; 403 | }; 404 | 405 | template 406 | struct index_of_type_ : index_of_type_ 407 | {}; 408 | } 409 | template 410 | inline constexpr size_t index_of_type = detail::index_of_type_::value; 411 | 412 | #endif // MZ_HAS_SNIPPET_META_INDEX_OF_TYPE 413 | 414 | #endif 415 | 416 | template 417 | struct type_list; 418 | 419 | #ifndef MZ_HAS_SNIPPET_TYPE_LIST 420 | #define MZ_HAS_SNIPPET_TYPE_LIST 421 | 422 | namespace detail 423 | { 424 | inline constexpr size_t type_list_page_size = MZ_TYPE_LIST_PAGE_SIZE; 425 | #if MZ_TYPE_LIST_HAS_JUMBO_PAGES 426 | inline constexpr size_t type_list_jumbo_page_size = 128; 427 | #else 428 | inline constexpr size_t type_list_jumbo_page_size = static_cast(-1); 429 | #endif 430 | 431 | #if MZ_HAS_INTEGER_SEQ 432 | template 433 | struct integer_sequence 434 | {}; 435 | template 436 | using index_sequence = integer_sequence; 437 | template 438 | using make_index_sequence = __make_integer_seq; 439 | #else 440 | using std::index_sequence; 441 | using std::make_index_sequence; 442 | #endif 443 | 444 | enum class type_list_selector_spec : int 445 | { 446 | first, 447 | skip_pages, 448 | low_index, 449 | compiler_builtin 450 | }; 451 | 452 | // clang-format off 453 | 454 | // selector 455 | template = type_list_jumbo_page_size ? type_list_selector_spec::skip_pages : ( 459 | N >= type_list_page_size ? type_list_selector_spec::skip_pages : ( 460 | type_list_selector_spec::low_index 461 | )))))> 462 | struct type_list_selector_; 463 | 464 | // clang-format on 465 | 466 | #if MZ_HAS_TYPE_PACK_ELEMENT 467 | 468 | // selector - selecting elements using a compiler builtin 469 | template 470 | struct type_list_selector_, N, type_list_selector_spec::compiler_builtin> 471 | { 472 | using type = __type_pack_element; 473 | }; 474 | 475 | #else 476 | 477 | // selector - first element 478 | template 479 | struct type_list_selector_, N, type_list_selector_spec::first> 480 | { 481 | using type = T0; 482 | }; 483 | 484 | // selector - skip pages 485 | template 486 | struct type_list_selector_ 487 | { 488 | // invokes the skip_pages specialization of the slicer 489 | using type = typename List::template slice::template select<0>; 490 | }; 491 | 492 | // selector - low-index elements 493 | #define MZ_MAKE_SELECTOR_1(N, N0, ...) \ 494 | template \ 495 | struct type_list_selector_, \ 496 | N, \ 497 | type_list_selector_spec::low_index> \ 498 | { \ 499 | using type = T##N; \ 500 | } 501 | #define MZ_MAKE_SELECTOR(...) MZ_FOR_EACH_FORCE_UNROLL(MZ_MAKE_SELECTOR_1(__VA_ARGS__)) 502 | 503 | template 504 | struct type_list_selector_, 1, type_list_selector_spec::low_index> 505 | { 506 | using type = T1; 507 | }; 508 | 509 | MZ_MAKE_SELECTOR(2, 0, 1, 2); 510 | MZ_MAKE_SELECTOR(3, 0, 1, 2, 3); 511 | MZ_MAKE_SELECTOR(4, 0, 1, 2, 3, 4); 512 | MZ_MAKE_SELECTOR(5, 0, 1, 2, 3, 4, 5); 513 | MZ_MAKE_SELECTOR(6, 0, 1, 2, 3, 4, 5, 6); 514 | MZ_MAKE_SELECTOR(7, MZ_0_TO_7); 515 | #if MZ_TYPE_LIST_PAGE_SIZE >= 16 516 | MZ_MAKE_SELECTOR(8, MZ_0_TO_7, 8); 517 | MZ_MAKE_SELECTOR(9, MZ_0_TO_7, 8, 9); 518 | MZ_MAKE_SELECTOR(10, MZ_0_TO_7, 8, 9, 10); 519 | MZ_MAKE_SELECTOR(11, MZ_0_TO_7, 8, 9, 10, 11); 520 | MZ_MAKE_SELECTOR(12, MZ_0_TO_7, 8, 9, 10, 11, 12); 521 | MZ_MAKE_SELECTOR(13, MZ_0_TO_7, 8, 9, 10, 11, 12, 13); 522 | MZ_MAKE_SELECTOR(14, MZ_0_TO_7, 8, 9, 10, 11, 12, 13, 14); 523 | MZ_MAKE_SELECTOR(15, MZ_0_TO_15); 524 | #endif 525 | #if MZ_TYPE_LIST_PAGE_SIZE >= 32 526 | MZ_MAKE_SELECTOR(16, MZ_0_TO_15, 16); 527 | MZ_MAKE_SELECTOR(17, MZ_0_TO_15, 16, 17); 528 | MZ_MAKE_SELECTOR(18, MZ_0_TO_15, 16, 17, 18); 529 | MZ_MAKE_SELECTOR(19, MZ_0_TO_15, 16, 17, 18, 19); 530 | MZ_MAKE_SELECTOR(20, MZ_0_TO_15, 16, 17, 18, 19, 20); 531 | MZ_MAKE_SELECTOR(21, MZ_0_TO_15, 16, 17, 18, 19, 20, 21); 532 | MZ_MAKE_SELECTOR(22, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22); 533 | MZ_MAKE_SELECTOR(23, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23); 534 | MZ_MAKE_SELECTOR(24, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24); 535 | MZ_MAKE_SELECTOR(25, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25); 536 | MZ_MAKE_SELECTOR(26, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); 537 | MZ_MAKE_SELECTOR(27, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); 538 | MZ_MAKE_SELECTOR(28, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); 539 | MZ_MAKE_SELECTOR(29, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29); 540 | MZ_MAKE_SELECTOR(30, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30); 541 | MZ_MAKE_SELECTOR(31, MZ_0_TO_31); 542 | #endif 543 | #if MZ_TYPE_LIST_PAGE_SIZE >= 48 544 | MZ_MAKE_SELECTOR(32, MZ_0_TO_31, 32); 545 | MZ_MAKE_SELECTOR(33, MZ_0_TO_31, 32, 33); 546 | MZ_MAKE_SELECTOR(34, MZ_0_TO_31, 32, 33, 34); 547 | MZ_MAKE_SELECTOR(35, MZ_0_TO_31, 32, 33, 34, 35); 548 | MZ_MAKE_SELECTOR(36, MZ_0_TO_31, 32, 33, 34, 35, 36); 549 | MZ_MAKE_SELECTOR(37, MZ_0_TO_31, 32, 33, 34, 35, 36, 37); 550 | MZ_MAKE_SELECTOR(38, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38); 551 | MZ_MAKE_SELECTOR(39, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39); 552 | MZ_MAKE_SELECTOR(40, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40); 553 | MZ_MAKE_SELECTOR(41, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41); 554 | MZ_MAKE_SELECTOR(42, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42); 555 | MZ_MAKE_SELECTOR(43, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43); 556 | MZ_MAKE_SELECTOR(44, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44); 557 | MZ_MAKE_SELECTOR(45, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45); 558 | MZ_MAKE_SELECTOR(46, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46); 559 | MZ_MAKE_SELECTOR(47, MZ_0_TO_47); 560 | #endif 561 | #if MZ_TYPE_LIST_PAGE_SIZE >= 64 562 | MZ_MAKE_SELECTOR(48, MZ_0_TO_47, 48); 563 | MZ_MAKE_SELECTOR(49, MZ_0_TO_47, 48, 49); 564 | MZ_MAKE_SELECTOR(50, MZ_0_TO_47, 48, 49, 50); 565 | MZ_MAKE_SELECTOR(51, MZ_0_TO_47, 48, 49, 50, 51); 566 | MZ_MAKE_SELECTOR(52, MZ_0_TO_47, 48, 49, 50, 51, 52); 567 | MZ_MAKE_SELECTOR(53, MZ_0_TO_47, 48, 49, 50, 51, 52, 53); 568 | MZ_MAKE_SELECTOR(54, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54); 569 | MZ_MAKE_SELECTOR(55, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55); 570 | MZ_MAKE_SELECTOR(56, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56); 571 | MZ_MAKE_SELECTOR(57, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57); 572 | MZ_MAKE_SELECTOR(58, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58); 573 | MZ_MAKE_SELECTOR(59, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59); 574 | MZ_MAKE_SELECTOR(60, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60); 575 | MZ_MAKE_SELECTOR(61, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61); 576 | MZ_MAKE_SELECTOR(62, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62); 577 | MZ_MAKE_SELECTOR(63, MZ_0_TO_63); 578 | #endif 579 | 580 | #undef MZ_MAKE_SELECTOR_1 581 | #undef MZ_MAKE_SELECTOR 582 | 583 | #endif // !MZ_HAS_TYPE_PACK_ELEMENT 584 | 585 | enum class type_list_slicer_spec : int 586 | { 587 | empty, 588 | first, 589 | all, 590 | skip_first_N, 591 | skip_jumbo_pages, 592 | skip_pages, 593 | prefix, 594 | single_low_index, 595 | single_compiler_builtin, 596 | arbitrary_range 597 | }; 598 | 599 | // clang-format off 600 | 601 | // slicer 602 | template = List::length ? type_list_slicer_spec::empty : ( 604 | Length == 1 && MZ_HAS_TYPE_PACK_ELEMENT ? type_list_slicer_spec::single_compiler_builtin : ( 605 | Start == 0 && Length == 1 ? type_list_slicer_spec::first : ( 606 | Start == 0 && List::length == Length ? type_list_slicer_spec::all : ( 607 | Start >= type_list_jumbo_page_size ? type_list_slicer_spec::skip_jumbo_pages : ( 608 | MZ_HAS_TYPE_PACK_ELEMENT ? type_list_slicer_spec::arbitrary_range : ( 609 | Start >= type_list_page_size ? type_list_slicer_spec::skip_pages : ( 610 | Length == 1 ? type_list_slicer_spec::single_low_index : ( 611 | Start == 0 && Length <= type_list_page_size ? type_list_slicer_spec::prefix : ( 612 | Start > 0 ? type_list_slicer_spec::skip_first_N : ( 613 | type_list_slicer_spec::arbitrary_range 614 | )))))))))))> 615 | struct type_list_slicer_; 616 | 617 | // clang-format on 618 | 619 | // slicer - empty range 620 | template 621 | struct type_list_slicer_ 622 | { 623 | using type = type_list<>; 624 | }; 625 | 626 | // slicer - arbitrary ranges 627 | template 628 | struct type_list_index_sequence_slicer_; 629 | template 630 | struct type_list_index_sequence_slicer_> 631 | { 632 | using type = type_list...>; 633 | }; 634 | template 635 | struct MZ_EMPTY_BASES type_list_slicer_ 636 | : type_list_index_sequence_slicer_> 637 | {}; 638 | 639 | // slicer - first element 640 | template 641 | struct type_list_slicer_, Start, Length, type_list_slicer_spec::first> 642 | { 643 | using type = type_list; 644 | }; 645 | 646 | // slicer - all (range is entire list) 647 | template 648 | struct type_list_slicer_ 649 | { 650 | using type = List; 651 | }; 652 | 653 | // slicer - skip jumbo pages (multiples of type_list_jumbo_page_size) 654 | #if MZ_TYPE_LIST_HAS_JUMBO_PAGES 655 | // clang-format off 656 | template < 657 | typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, 658 | typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14, typename T15, 659 | typename T16, typename T17, typename T18, typename T19, typename T20, typename T21, typename T22, typename T23, 660 | typename T24, typename T25, typename T26, typename T27, typename T28, typename T29, typename T30, typename T31, 661 | typename T32, typename T33, typename T34, typename T35, typename T36, typename T37, typename T38, typename T39, 662 | typename T40, typename T41, typename T42, typename T43, typename T44, typename T45, typename T46, typename T47, 663 | typename T48, typename T49, typename T50, typename T51, typename T52, typename T53, typename T54, typename T55, 664 | typename T56, typename T57, typename T58, typename T59, typename T60, typename T61, typename T62, typename T63, 665 | typename T64, typename T65, typename T66, typename T67, typename T68, typename T69, typename T70, typename T71, 666 | typename T72, typename T73, typename T74, typename T75, typename T76, typename T77, typename T78, typename T79, 667 | typename T80, typename T81, typename T82, typename T83, typename T84, typename T85, typename T86, typename T87, 668 | typename T88, typename T89, typename T90, typename T91, typename T92, typename T93, typename T94, typename T95, 669 | typename T96, typename T97, typename T98, typename T99, typename T100, typename T101, typename T102, typename T103, 670 | typename T104, typename T105, typename T106, typename T107, typename T108, typename T109, typename T110, typename T111, 671 | typename T112, typename T113, typename T114, typename T115, typename T116, typename T117, typename T118, typename T119, 672 | typename T120, typename T121, typename T122, typename T123, typename T124, typename T125, typename T126, typename T127, 673 | typename... T, size_t Start, size_t Length 674 | > 675 | struct type_list_slicer_< 676 | type_list< 677 | T0, T1, T2, T3, T4, T5, T6, T7, 678 | T8, T9, T10, T11, T12, T13, T14, T15, 679 | T16, T17, T18, T19, T20, T21, T22, T23, 680 | T24, T25, T26, T27, T28, T29, T30, T31, 681 | T32, T33, T34, T35, T36, T37, T38, T39, 682 | T40, T41, T42, T43, T44, T45, T46, T47, 683 | T48, T49, T50, T51, T52, T53, T54, T55, 684 | T56, T57, T58, T59, T60, T61, T62, T63, 685 | T64, T65, T66, T67, T68, T69, T70, T71, 686 | T72, T73, T74, T75, T76, T77, T78, T79, 687 | T80, T81, T82, T83, T84, T85, T86, T87, 688 | T88, T89, T90, T91, T92, T93, T94, T95, 689 | T96, T97, T98, T99, T100, T101, T102, T103, 690 | T104, T105, T106, T107, T108, T109, T110, T111, 691 | T112, T113, T114, T115, T116, T117, T118, T119, 692 | T120, T121, T122, T123, T124, T125, T126, T127, 693 | T... 694 | >, 695 | Start, Length, type_list_slicer_spec::skip_jumbo_pages 696 | > 697 | { 698 | using type = typename type_list::template slice; 699 | }; 700 | // clang-format on 701 | #endif // MZ_TYPE_LIST_HAS_JUMBO_PAGES 702 | 703 | #if MZ_HAS_TYPE_PACK_ELEMENT 704 | 705 | // slicer - selecting arbitrary single element spans using a compiler builtin 706 | template 707 | struct type_list_slicer_, Start, 1, type_list_slicer_spec::single_compiler_builtin> 708 | { 709 | using type = type_list<__type_pack_element>; 710 | }; 711 | 712 | #else 713 | 714 | // slicer - skip pages (multiples of type_list_page_size) 715 | template 716 | struct type_list_slicer_ 717 | { 718 | // repeatedly invokes the skip_first_N specialization until Start is < type_list_page_size 719 | using type = typename type_list_slicer_::type // 723 | ::template slice; 724 | }; 725 | 726 | // slicer - low-index elements 727 | #define MZ_MAKE_SINGLE_ELEMENT_SLICER_1(N, N0, ...) \ 728 | template \ 729 | struct type_list_slicer_, \ 730 | N, \ 731 | 1, \ 732 | type_list_slicer_spec::single_low_index> \ 733 | { \ 734 | using type = type_list; \ 735 | } 736 | #define MZ_MAKE_SINGLE_ELEMENT_SLICER(...) \ 737 | MZ_FOR_EACH_FORCE_UNROLL(MZ_MAKE_SINGLE_ELEMENT_SLICER_1(__VA_ARGS__)) 738 | 739 | template 740 | struct type_list_slicer_, 1, 1, type_list_slicer_spec::single_low_index> 741 | { 742 | using type = type_list; 743 | }; 744 | 745 | MZ_MAKE_SINGLE_ELEMENT_SLICER(2, 0, 1, 2); 746 | MZ_MAKE_SINGLE_ELEMENT_SLICER(3, 0, 1, 2, 3); 747 | MZ_MAKE_SINGLE_ELEMENT_SLICER(4, 0, 1, 2, 3, 4); 748 | MZ_MAKE_SINGLE_ELEMENT_SLICER(5, 0, 1, 2, 3, 4, 5); 749 | MZ_MAKE_SINGLE_ELEMENT_SLICER(6, 0, 1, 2, 3, 4, 5, 6); 750 | MZ_MAKE_SINGLE_ELEMENT_SLICER(7, MZ_0_TO_7); 751 | #if MZ_TYPE_LIST_PAGE_SIZE >= 16 752 | MZ_MAKE_SINGLE_ELEMENT_SLICER(8, MZ_0_TO_7, 8); 753 | MZ_MAKE_SINGLE_ELEMENT_SLICER(9, MZ_0_TO_7, 8, 9); 754 | MZ_MAKE_SINGLE_ELEMENT_SLICER(10, MZ_0_TO_7, 8, 9, 10); 755 | MZ_MAKE_SINGLE_ELEMENT_SLICER(11, MZ_0_TO_7, 8, 9, 10, 11); 756 | MZ_MAKE_SINGLE_ELEMENT_SLICER(12, MZ_0_TO_7, 8, 9, 10, 11, 12); 757 | MZ_MAKE_SINGLE_ELEMENT_SLICER(13, MZ_0_TO_7, 8, 9, 10, 11, 12, 13); 758 | MZ_MAKE_SINGLE_ELEMENT_SLICER(14, MZ_0_TO_7, 8, 9, 10, 11, 12, 13, 14); 759 | MZ_MAKE_SINGLE_ELEMENT_SLICER(15, MZ_0_TO_15); 760 | #endif 761 | #if MZ_TYPE_LIST_PAGE_SIZE >= 32 762 | MZ_MAKE_SINGLE_ELEMENT_SLICER(16, MZ_0_TO_15, 16); 763 | MZ_MAKE_SINGLE_ELEMENT_SLICER(17, MZ_0_TO_15, 16, 17); 764 | MZ_MAKE_SINGLE_ELEMENT_SLICER(18, MZ_0_TO_15, 16, 17, 18); 765 | MZ_MAKE_SINGLE_ELEMENT_SLICER(19, MZ_0_TO_15, 16, 17, 18, 19); 766 | MZ_MAKE_SINGLE_ELEMENT_SLICER(20, MZ_0_TO_15, 16, 17, 18, 19, 20); 767 | MZ_MAKE_SINGLE_ELEMENT_SLICER(21, MZ_0_TO_15, 16, 17, 18, 19, 20, 21); 768 | MZ_MAKE_SINGLE_ELEMENT_SLICER(22, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22); 769 | MZ_MAKE_SINGLE_ELEMENT_SLICER(23, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23); 770 | MZ_MAKE_SINGLE_ELEMENT_SLICER(24, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24); 771 | MZ_MAKE_SINGLE_ELEMENT_SLICER(25, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25); 772 | MZ_MAKE_SINGLE_ELEMENT_SLICER(26, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); 773 | MZ_MAKE_SINGLE_ELEMENT_SLICER(27, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); 774 | MZ_MAKE_SINGLE_ELEMENT_SLICER(28, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); 775 | MZ_MAKE_SINGLE_ELEMENT_SLICER(29, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29); 776 | MZ_MAKE_SINGLE_ELEMENT_SLICER(30, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30); 777 | MZ_MAKE_SINGLE_ELEMENT_SLICER(31, MZ_0_TO_31); 778 | #endif 779 | #if MZ_TYPE_LIST_PAGE_SIZE >= 48 780 | MZ_MAKE_SINGLE_ELEMENT_SLICER(32, MZ_0_TO_31, 32); 781 | MZ_MAKE_SINGLE_ELEMENT_SLICER(33, MZ_0_TO_31, 32, 33); 782 | MZ_MAKE_SINGLE_ELEMENT_SLICER(34, MZ_0_TO_31, 32, 33, 34); 783 | MZ_MAKE_SINGLE_ELEMENT_SLICER(35, MZ_0_TO_31, 32, 33, 34, 35); 784 | MZ_MAKE_SINGLE_ELEMENT_SLICER(36, MZ_0_TO_31, 32, 33, 34, 35, 36); 785 | MZ_MAKE_SINGLE_ELEMENT_SLICER(37, MZ_0_TO_31, 32, 33, 34, 35, 36, 37); 786 | MZ_MAKE_SINGLE_ELEMENT_SLICER(38, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38); 787 | MZ_MAKE_SINGLE_ELEMENT_SLICER(39, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39); 788 | MZ_MAKE_SINGLE_ELEMENT_SLICER(40, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40); 789 | MZ_MAKE_SINGLE_ELEMENT_SLICER(41, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41); 790 | MZ_MAKE_SINGLE_ELEMENT_SLICER(42, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42); 791 | MZ_MAKE_SINGLE_ELEMENT_SLICER(43, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43); 792 | MZ_MAKE_SINGLE_ELEMENT_SLICER(44, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44); 793 | MZ_MAKE_SINGLE_ELEMENT_SLICER(45, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45); 794 | MZ_MAKE_SINGLE_ELEMENT_SLICER(46, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46); 795 | MZ_MAKE_SINGLE_ELEMENT_SLICER(47, MZ_0_TO_47); 796 | #endif 797 | #if MZ_TYPE_LIST_PAGE_SIZE >= 64 798 | MZ_MAKE_SINGLE_ELEMENT_SLICER(48, MZ_0_TO_47, 48); 799 | MZ_MAKE_SINGLE_ELEMENT_SLICER(49, MZ_0_TO_47, 48, 49); 800 | MZ_MAKE_SINGLE_ELEMENT_SLICER(50, MZ_0_TO_47, 48, 49, 50); 801 | MZ_MAKE_SINGLE_ELEMENT_SLICER(51, MZ_0_TO_47, 48, 49, 50, 51); 802 | MZ_MAKE_SINGLE_ELEMENT_SLICER(52, MZ_0_TO_47, 48, 49, 50, 51, 52); 803 | MZ_MAKE_SINGLE_ELEMENT_SLICER(53, MZ_0_TO_47, 48, 49, 50, 51, 52, 53); 804 | MZ_MAKE_SINGLE_ELEMENT_SLICER(54, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54); 805 | MZ_MAKE_SINGLE_ELEMENT_SLICER(55, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55); 806 | MZ_MAKE_SINGLE_ELEMENT_SLICER(56, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56); 807 | MZ_MAKE_SINGLE_ELEMENT_SLICER(57, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57); 808 | MZ_MAKE_SINGLE_ELEMENT_SLICER(58, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58); 809 | MZ_MAKE_SINGLE_ELEMENT_SLICER(59, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59); 810 | MZ_MAKE_SINGLE_ELEMENT_SLICER(60, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60); 811 | MZ_MAKE_SINGLE_ELEMENT_SLICER(61, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61); 812 | MZ_MAKE_SINGLE_ELEMENT_SLICER(62, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62); 813 | MZ_MAKE_SINGLE_ELEMENT_SLICER(63, MZ_0_TO_63); 814 | #endif 815 | 816 | #undef MZ_MAKE_SINGLE_ELEMENT_SLICER_1 817 | #undef MZ_MAKE_SINGLE_ELEMENT_SLICER 818 | 819 | // slicer - prefixes 820 | #define MZ_MAKE_PREFIX_SLICER_1(N0, ...) \ 821 | template \ 822 | struct type_list_slicer_, \ 823 | 0, \ 824 | MZ_COUNT_VA_ARGS(__VA_ARGS__) + 1, \ 825 | type_list_slicer_spec::prefix> \ 826 | { \ 827 | using type = type_list; \ 828 | } 829 | #define MZ_MAKE_PREFIX_SLICER(...) MZ_FOR_EACH_FORCE_UNROLL(MZ_MAKE_PREFIX_SLICER_1(__VA_ARGS__)) 830 | 831 | template 832 | struct type_list_slicer_, 0, 2, type_list_slicer_spec::prefix> 833 | { 834 | using type = type_list; 835 | }; 836 | 837 | MZ_MAKE_PREFIX_SLICER(0, 1, 2); 838 | MZ_MAKE_PREFIX_SLICER(0, 1, 2, 3); 839 | MZ_MAKE_PREFIX_SLICER(0, 1, 2, 3, 4); 840 | MZ_MAKE_PREFIX_SLICER(0, 1, 2, 3, 4, 5); 841 | MZ_MAKE_PREFIX_SLICER(0, 1, 2, 3, 4, 5, 6); 842 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7); 843 | #if MZ_TYPE_LIST_PAGE_SIZE >= 16 844 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8); 845 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9); 846 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9, 10); 847 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9, 10, 11); 848 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9, 10, 11, 12); 849 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9, 10, 11, 12, 13); 850 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_7, 8, 9, 10, 11, 12, 13, 14); 851 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15); 852 | #endif 853 | #if MZ_TYPE_LIST_PAGE_SIZE >= 32 854 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16); 855 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17); 856 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18); 857 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19); 858 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20); 859 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21); 860 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22); 861 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23); 862 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24); 863 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25); 864 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); 865 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); 866 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); 867 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29); 868 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30); 869 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31); 870 | #endif 871 | #if MZ_TYPE_LIST_PAGE_SIZE >= 48 872 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32); 873 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33); 874 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34); 875 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35); 876 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36); 877 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37); 878 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38); 879 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39); 880 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40); 881 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41); 882 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42); 883 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43); 884 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44); 885 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45); 886 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46); 887 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47); 888 | #endif 889 | #if MZ_TYPE_LIST_PAGE_SIZE >= 64 890 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48); 891 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49); 892 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50); 893 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51); 894 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52); 895 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53); 896 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54); 897 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55); 898 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56); 899 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57); 900 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58); 901 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59); 902 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60); 903 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61); 904 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62); 905 | MZ_MAKE_PREFIX_SLICER(MZ_0_TO_63); 906 | #endif 907 | 908 | #undef MZ_MAKE_PREFIX_SLICER_1 909 | #undef MZ_MAKE_PREFIX_SLICER 910 | 911 | // slicer - skip first N 912 | #define MZ_MAKE_SKIP_N_SLICER_1(N, N0, N1, ...) \ 913 | template < \ 914 | typename T##N0, \ 915 | typename T##N1 MZ_FOR_EACH(MZ_MAKE_INDEXED_TPARAM, __VA_ARGS__), typename... T, size_t Length> \ 916 | struct type_list_slicer_, \ 917 | N, \ 918 | Length, \ 919 | type_list_slicer_spec::skip_first_N> \ 920 | { \ 921 | using type = typename type_list::template slice<0, Length>; \ 922 | } 923 | #define MZ_MAKE_SKIP_N_SLICER(...) MZ_FOR_EACH_FORCE_UNROLL(MZ_MAKE_SKIP_N_SLICER_1(__VA_ARGS__)) 924 | 925 | template 926 | struct type_list_slicer_, 1, Length, type_list_slicer_spec::skip_first_N> 927 | { 928 | using type = typename type_list::template slice<0, Length>; 929 | }; 930 | 931 | template 932 | struct type_list_slicer_, 2, Length, type_list_slicer_spec::skip_first_N> 933 | { 934 | using type = typename type_list::template slice<0, Length>; 935 | }; 936 | 937 | MZ_MAKE_SKIP_N_SLICER(3, 0, 1, 2, 3); 938 | MZ_MAKE_SKIP_N_SLICER(4, 0, 1, 2, 3, 4); 939 | MZ_MAKE_SKIP_N_SLICER(5, 0, 1, 2, 3, 4, 5); 940 | MZ_MAKE_SKIP_N_SLICER(6, 0, 1, 2, 3, 4, 5, 6); 941 | MZ_MAKE_SKIP_N_SLICER(7, MZ_0_TO_7); 942 | MZ_MAKE_SKIP_N_SLICER(8, MZ_0_TO_7, 8); 943 | #if MZ_TYPE_LIST_PAGE_SIZE >= 16 944 | MZ_MAKE_SKIP_N_SLICER(9, MZ_0_TO_7, 8, 9); 945 | MZ_MAKE_SKIP_N_SLICER(10, MZ_0_TO_7, 8, 9, 10); 946 | MZ_MAKE_SKIP_N_SLICER(11, MZ_0_TO_7, 8, 9, 10, 11); 947 | MZ_MAKE_SKIP_N_SLICER(12, MZ_0_TO_7, 8, 9, 10, 11, 12); 948 | MZ_MAKE_SKIP_N_SLICER(13, MZ_0_TO_7, 8, 9, 10, 11, 12, 13); 949 | MZ_MAKE_SKIP_N_SLICER(14, MZ_0_TO_7, 8, 9, 10, 11, 12, 13, 14); 950 | MZ_MAKE_SKIP_N_SLICER(15, MZ_0_TO_15); 951 | MZ_MAKE_SKIP_N_SLICER(16, MZ_0_TO_15, 16); 952 | #endif 953 | #if MZ_TYPE_LIST_PAGE_SIZE >= 32 954 | MZ_MAKE_SKIP_N_SLICER(17, MZ_0_TO_15, 16, 17); 955 | MZ_MAKE_SKIP_N_SLICER(18, MZ_0_TO_15, 16, 17, 18); 956 | MZ_MAKE_SKIP_N_SLICER(19, MZ_0_TO_15, 16, 17, 18, 19); 957 | MZ_MAKE_SKIP_N_SLICER(20, MZ_0_TO_15, 16, 17, 18, 19, 20); 958 | MZ_MAKE_SKIP_N_SLICER(21, MZ_0_TO_15, 16, 17, 18, 19, 20, 21); 959 | MZ_MAKE_SKIP_N_SLICER(22, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22); 960 | MZ_MAKE_SKIP_N_SLICER(23, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23); 961 | MZ_MAKE_SKIP_N_SLICER(24, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24); 962 | MZ_MAKE_SKIP_N_SLICER(25, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25); 963 | MZ_MAKE_SKIP_N_SLICER(26, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26); 964 | MZ_MAKE_SKIP_N_SLICER(27, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); 965 | MZ_MAKE_SKIP_N_SLICER(28, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28); 966 | MZ_MAKE_SKIP_N_SLICER(29, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29); 967 | MZ_MAKE_SKIP_N_SLICER(30, MZ_0_TO_15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30); 968 | MZ_MAKE_SKIP_N_SLICER(31, MZ_0_TO_31); 969 | MZ_MAKE_SKIP_N_SLICER(32, MZ_0_TO_31, 32); 970 | #endif 971 | #if MZ_TYPE_LIST_PAGE_SIZE >= 48 972 | MZ_MAKE_SKIP_N_SLICER(33, MZ_0_TO_31, 32, 33); 973 | MZ_MAKE_SKIP_N_SLICER(34, MZ_0_TO_31, 32, 33, 34); 974 | MZ_MAKE_SKIP_N_SLICER(35, MZ_0_TO_31, 32, 33, 34, 35); 975 | MZ_MAKE_SKIP_N_SLICER(36, MZ_0_TO_31, 32, 33, 34, 35, 36); 976 | MZ_MAKE_SKIP_N_SLICER(37, MZ_0_TO_31, 32, 33, 34, 35, 36, 37); 977 | MZ_MAKE_SKIP_N_SLICER(38, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38); 978 | MZ_MAKE_SKIP_N_SLICER(39, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39); 979 | MZ_MAKE_SKIP_N_SLICER(40, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40); 980 | MZ_MAKE_SKIP_N_SLICER(41, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41); 981 | MZ_MAKE_SKIP_N_SLICER(42, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42); 982 | MZ_MAKE_SKIP_N_SLICER(43, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43); 983 | MZ_MAKE_SKIP_N_SLICER(44, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44); 984 | MZ_MAKE_SKIP_N_SLICER(45, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45); 985 | MZ_MAKE_SKIP_N_SLICER(46, MZ_0_TO_31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46); 986 | MZ_MAKE_SKIP_N_SLICER(47, MZ_0_TO_47); 987 | MZ_MAKE_SKIP_N_SLICER(48, MZ_0_TO_47, 48); 988 | #endif 989 | #if MZ_TYPE_LIST_PAGE_SIZE >= 64 990 | MZ_MAKE_SKIP_N_SLICER(49, MZ_0_TO_47, 48, 49); 991 | MZ_MAKE_SKIP_N_SLICER(50, MZ_0_TO_47, 48, 49, 50); 992 | MZ_MAKE_SKIP_N_SLICER(51, MZ_0_TO_47, 48, 49, 50, 51); 993 | MZ_MAKE_SKIP_N_SLICER(52, MZ_0_TO_47, 48, 49, 50, 51, 52); 994 | MZ_MAKE_SKIP_N_SLICER(53, MZ_0_TO_47, 48, 49, 50, 51, 52, 53); 995 | MZ_MAKE_SKIP_N_SLICER(54, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54); 996 | MZ_MAKE_SKIP_N_SLICER(55, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55); 997 | MZ_MAKE_SKIP_N_SLICER(56, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56); 998 | MZ_MAKE_SKIP_N_SLICER(57, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57); 999 | MZ_MAKE_SKIP_N_SLICER(58, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58); 1000 | MZ_MAKE_SKIP_N_SLICER(59, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59); 1001 | MZ_MAKE_SKIP_N_SLICER(60, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60); 1002 | MZ_MAKE_SKIP_N_SLICER(61, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61); 1003 | MZ_MAKE_SKIP_N_SLICER(62, MZ_0_TO_47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62); 1004 | MZ_MAKE_SKIP_N_SLICER(63, MZ_0_TO_63); 1005 | MZ_MAKE_SKIP_N_SLICER(64, MZ_0_TO_63, 64); 1006 | #endif 1007 | 1008 | #undef MZ_MAKE_SKIP_N_SLICER_1 1009 | #undef MZ_MAKE_SKIP_N_SLICER 1010 | 1011 | #endif // !MZ_HAS_TYPE_PACK_ELEMENT 1012 | 1013 | // clang-format on 1014 | 1015 | // concatenate 1016 | 1017 | template 1018 | struct type_list_concatenate_; 1019 | 1020 | template <> 1021 | struct type_list_concatenate_<> 1022 | { 1023 | using types = type_list<>; 1024 | }; 1025 | 1026 | template 1027 | struct type_list_concatenate_> 1028 | { 1029 | using types = type_list; 1030 | }; 1031 | 1032 | template 1033 | struct type_list_concatenate_, type_list> 1034 | { 1035 | using types = type_list; 1036 | }; 1037 | 1038 | template 1039 | struct type_list_concatenate_, type_list, V...> 1040 | { 1041 | using types = typename type_list_concatenate_, V...>::types; 1042 | }; 1043 | 1044 | // flatten 1045 | 1046 | template 1047 | struct type_list_flatten_ 1048 | { 1049 | using types = type_list; 1050 | }; 1051 | 1052 | template <> 1053 | struct type_list_flatten_> 1054 | { 1055 | using types = type_list<>; 1056 | }; 1057 | 1058 | template 1059 | struct type_list_flatten_> 1060 | { 1061 | using types = typename type_list_concatenate_::types...>::types; 1062 | }; 1063 | 1064 | template 1065 | using type_list_flatten = typename type_list_concatenate_::types...>::types; 1066 | 1067 | // remove 1068 | 1069 | template 1070 | struct type_list_remove_ 1071 | { 1072 | using types = type_list; 1073 | }; 1074 | 1075 | template 1076 | struct type_list_remove_ 1077 | { 1078 | using types = type_list<>; 1079 | }; 1080 | 1081 | template 1082 | using type_list_remove = typename type_list_concatenate_::types...>::types; 1083 | } // ::detail 1084 | 1085 | template <> 1086 | struct type_list<> 1087 | { 1088 | static constexpr size_t length = 0; 1089 | 1090 | // these are clearly nonsense but needed for templates to not cause substitution failure 1091 | 1092 | template 1093 | using select = typename detail::type_list_selector_, Index>::type; 1094 | 1095 | template 1096 | using slice = type_list<>; 1097 | 1098 | template 1099 | static constexpr size_t index_of = static_cast(-1); 1100 | 1101 | template 1102 | static constexpr bool contains = false; 1103 | 1104 | using flatten = type_list<>; 1105 | 1106 | template 1107 | using remove = type_list<>; 1108 | 1109 | template 1110 | using append = type_list; 1111 | 1112 | template 1113 | using prepend = type_list; 1114 | }; 1115 | 1116 | template 1117 | struct type_list 1118 | { 1119 | static constexpr size_t length = 1; 1120 | 1121 | using first = T; 1122 | using type = first; 1123 | 1124 | #if MZ_HAS_TYPE_PACK_ELEMENT 1125 | template 1126 | using select = __type_pack_element; 1127 | #else 1128 | template 1129 | using select = typename detail::type_list_selector_, Index>::type; 1130 | #endif 1131 | 1132 | template 1133 | using slice = typename detail::type_list_slicer_, Start, Length>::type; 1134 | 1135 | template 1136 | static constexpr size_t index_of = index_of_type; 1137 | 1138 | template 1139 | static constexpr bool contains = std::is_same_v; 1140 | 1141 | using flatten = detail::type_list_flatten; 1142 | 1143 | template 1144 | using remove = detail::type_list_remove; 1145 | 1146 | template 1147 | using append = type_list; 1148 | 1149 | template 1150 | using prepend = type_list; 1151 | }; 1152 | 1153 | template 1154 | struct type_list 1155 | { 1156 | static constexpr size_t length = 1 + sizeof...(T); 1157 | 1158 | using first = T0; 1159 | 1160 | #if MZ_HAS_TYPE_PACK_ELEMENT 1161 | template 1162 | using select = __type_pack_element; 1163 | #else 1164 | template 1165 | using select = typename detail::type_list_selector_, Index>::type; 1166 | #endif 1167 | 1168 | template 1169 | using slice = typename detail::type_list_slicer_, Start, Length>::type; 1170 | 1171 | template 1172 | static constexpr size_t index_of = index_of_type; 1173 | 1174 | template 1175 | static constexpr bool contains = (std::is_same_v || ... || std::is_same_v); 1176 | 1177 | using flatten = detail::type_list_flatten; 1178 | 1179 | template 1180 | using remove = detail::type_list_remove; 1181 | 1182 | template 1183 | using append = type_list; 1184 | 1185 | template 1186 | using prepend = type_list; 1187 | }; 1188 | 1189 | template 1190 | using type_tag = type_list; 1191 | 1192 | #endif // MZ_HAS_SNIPPET_TYPE_LIST 1193 | 1194 | } 1195 | 1196 | #undef MZ_TYPE_LIST_PAGE_SIZE 1197 | #undef MZ_TYPE_LIST_HAS_JUMBO_PAGES 1198 | #undef MZ_HAS_TYPE_PACK_ELEMENT 1199 | #undef MZ_HAS_INTEGER_SEQ 1200 | #undef MZ_MAKE_INDEXED_TPARAM 1201 | #undef MZ_MAKE_INDEXED_TARG 1202 | #undef MZ_0_TO_7 1203 | #undef MZ_0_TO_15 1204 | #undef MZ_0_TO_31 1205 | #undef MZ_0_TO_47 1206 | #undef MZ_0_TO_63 1207 | 1208 | #endif // MZ_TYPE_LIST_HPP 1209 | -------------------------------------------------------------------------------- /include/mz/type_list.hpp.in: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // {% namespaces::main %}::type_list 4 | // https://github.com/marzer/type_list 5 | // SPDX-License-Identifier: MIT 6 | // 7 | //---------------------------------------------------------------------------------------------------------------------- 8 | //% generated_header_preamble 9 | //---------------------------------------------------------------------------------------------------------------------- 10 | #ifndef {% macros::prefix %}TYPE_LIST_HPP 11 | #define {% macros::prefix %}TYPE_LIST_HPP 12 | 13 | #define {% macros::prefix %}TYPE_LIST_VERSION_MAJOR 1 14 | #define {% macros::prefix %}TYPE_LIST_VERSION_MINOR 0 15 | #define {% macros::prefix %}TYPE_LIST_VERSION_PATCH 0 16 | 17 | //% preprocessor::make_version 18 | //% preprocessor::compilers::clang 19 | //% preprocessor::compilers::msvc_like 20 | 21 | //% preprocessor::concat 22 | //% preprocessor::has_builtin 23 | //% preprocessor::for_each 24 | //% preprocessor::count_va_args 25 | //% preprocessor::comma 26 | //% preprocessor::declspec 27 | //% preprocessor::empty_bases 28 | 29 | //% type_list::header 30 | 31 | #include 32 | #include 33 | 34 | namespace {% namespaces::main %} 35 | { 36 | using std::size_t; 37 | 38 | #if 1 39 | //% meta::always_false guarded 40 | //% meta::index_of_type guarded 41 | #endif 42 | 43 | template 44 | struct type_list; 45 | 46 | //% type_list guarded 47 | } 48 | 49 | //% type_list::footer 50 | 51 | #endif // {% macros::prefix %}TYPE_LIST_HPP 52 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | project( 7 | 'type_list', 8 | 'cpp', 9 | version : '1.0.0', 10 | meson_version : '>=0.60.0', 11 | license : 'MIT', 12 | default_options : [ 'cpp_std=c++17' ] 13 | ) 14 | 15 | subdir('include') 16 | 17 | type_list_dep = declare_dependency( 18 | include_directories: include_dir 19 | ) 20 | 21 | if not meson.is_subproject() and get_option('build_examples') 22 | subdir('examples') 23 | endif 24 | 25 | if not meson.is_subproject() and get_option('build_tests') 26 | subdir('tests') 27 | endif 28 | 29 | 30 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('build_tests', type: 'boolean', value: true, description: 'Build tests') 2 | option('build_examples', type: 'boolean', value: true, description: 'Build examples') 3 | -------------------------------------------------------------------------------- /tests/main.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | // Copyright (c) Mark Gillard 3 | // See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | // SPDX-License-Identifier: MIT 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace mz; 11 | 12 | template 13 | using index_tag = std::integral_constant; 14 | 15 | template 16 | struct type_list_maker; 17 | 18 | template 19 | struct type_list_maker> 20 | { 21 | using type = type_list...>; 22 | }; 23 | 24 | template 25 | using make_type_list = typename type_list_maker>::type; 26 | 27 | using test_type_list = make_type_list<0, 100>; 28 | 29 | static_assert(test_type_list::length == 100); 30 | 31 | static_assert(std::is_same_v>); 32 | 33 | static_assert(std::is_same_v, index_tag<0>>); 34 | static_assert(std::is_same_v, index_tag<1>>); 35 | static_assert(std::is_same_v, index_tag<2>>); 36 | static_assert(std::is_same_v, index_tag<3>>); 37 | static_assert(std::is_same_v, index_tag<4>>); 38 | static_assert(std::is_same_v, index_tag<5>>); 39 | static_assert(std::is_same_v, index_tag<6>>); 40 | static_assert(std::is_same_v, index_tag<7>>); 41 | static_assert(std::is_same_v, index_tag<8>>); 42 | static_assert(std::is_same_v, index_tag<9>>); 43 | static_assert(std::is_same_v, index_tag<10>>); 44 | static_assert(std::is_same_v, index_tag<60>>); 45 | static_assert(std::is_same_v, index_tag<70>>); 46 | static_assert(std::is_same_v, index_tag<99>>); 47 | 48 | static_assert(std::is_same_v, make_type_list<0, 1>>); 49 | static_assert(std::is_same_v, make_type_list<1, 1>>); 50 | static_assert(std::is_same_v, make_type_list<2, 1>>); 51 | static_assert(std::is_same_v, make_type_list<3, 1>>); 52 | static_assert(std::is_same_v, make_type_list<4, 1>>); 53 | static_assert(std::is_same_v, make_type_list<5, 1>>); 54 | static_assert(std::is_same_v, make_type_list<6, 1>>); 55 | static_assert(std::is_same_v, make_type_list<7, 1>>); 56 | static_assert(std::is_same_v, make_type_list<8, 1>>); 57 | static_assert(std::is_same_v, make_type_list<9, 1>>); 58 | static_assert(std::is_same_v, make_type_list<10, 1>>); 59 | static_assert(std::is_same_v, make_type_list<60, 1>>); 60 | static_assert(std::is_same_v, make_type_list<70, 1>>); 61 | static_assert(std::is_same_v, make_type_list<99, 1>>); 62 | 63 | static_assert(std::is_same_v, make_type_list<0, 5>>); 64 | static_assert(std::is_same_v, make_type_list<1, 5>>); 65 | static_assert(std::is_same_v, make_type_list<2, 5>>); 66 | static_assert(std::is_same_v, make_type_list<3, 5>>); 67 | static_assert(std::is_same_v, make_type_list<4, 5>>); 68 | static_assert(std::is_same_v, make_type_list<5, 5>>); 69 | static_assert(std::is_same_v, make_type_list<6, 5>>); 70 | static_assert(std::is_same_v, make_type_list<7, 5>>); 71 | static_assert(std::is_same_v, make_type_list<8, 5>>); 72 | static_assert(std::is_same_v, make_type_list<9, 5>>); 73 | static_assert(std::is_same_v, make_type_list<10, 5>>); 74 | static_assert(std::is_same_v, make_type_list<60, 5>>); 75 | static_assert(std::is_same_v, make_type_list<70, 5>>); 76 | 77 | static_assert(test_type_list::index_of> == 0); 78 | static_assert(test_type_list::index_of> == 1); 79 | static_assert(test_type_list::index_of> == 2); 80 | static_assert(test_type_list::index_of> == 3); 81 | static_assert(test_type_list::index_of> == 4); 82 | static_assert(test_type_list::index_of> == 5); 83 | static_assert(test_type_list::index_of> == 6); 84 | static_assert(test_type_list::index_of> == 7); 85 | static_assert(test_type_list::index_of> == 8); 86 | static_assert(test_type_list::index_of> == 9); 87 | static_assert(test_type_list::index_of> == 10); 88 | static_assert(test_type_list::index_of> == 60); 89 | static_assert(test_type_list::index_of> == 70); 90 | static_assert(test_type_list::index_of> == 99); 91 | 92 | static_assert(std::is_same_v::flatten, // 93 | type_list<>>); 94 | static_assert(std::is_same_v>::flatten, // 95 | type_list<>>); 96 | static_assert(std::is_same_v>>::flatten, // 97 | type_list<>>); 98 | static_assert(std::is_same_v::flatten, // 99 | type_list>); 100 | static_assert(std::is_same_v>::flatten, // 101 | type_list>); 102 | static_assert(std::is_same_v::flatten, // 103 | type_list>); 104 | static_assert(std::is_same_v, int>::flatten, // 105 | type_list>); 106 | static_assert(std::is_same_v, type_list>>::flatten, 107 | type_list>); 108 | 109 | static_assert(std::is_same_v::remove, // 110 | type_list<>>); 111 | static_assert(std::is_same_v::remove, // 112 | type_list<>>); 113 | static_assert(std::is_same_v::remove, // 114 | type_list<>>); 115 | static_assert(std::is_same_v::remove, // 116 | type_list>); 117 | static_assert(std::is_same_v, float, void, void, void, double, void>::remove, // 118 | type_list, float, double>>); 119 | 120 | static_assert(std::is_same_v::append, // 121 | type_list>); 122 | static_assert(std::is_same_v::append, // 123 | type_list>); 124 | static_assert(std::is_same_v::append, // 125 | type_list>); 126 | static_assert(std::is_same_v::append, // 127 | type_list>); 128 | 129 | static_assert(std::is_same_v::prepend, // 130 | type_list>); 131 | static_assert(std::is_same_v::prepend, // 132 | type_list>); 133 | static_assert(std::is_same_v::prepend, // 134 | type_list>); 135 | static_assert(std::is_same_v::prepend, // 136 | type_list>); 137 | 138 | static_assert(type_list::contains); 139 | static_assert(type_list::contains); 140 | static_assert(type_list::contains); 141 | static_assert(!type_list::contains); 142 | 143 | static_assert(type_list::contains); 144 | static_assert(type_list::contains); 145 | static_assert(!type_list::contains); 146 | static_assert(!type_list::contains); 147 | 148 | static_assert(type_list::contains); 149 | static_assert(!type_list::contains); 150 | static_assert(!type_list::contains); 151 | static_assert(!type_list::contains); 152 | 153 | static_assert(!type_list<>::contains); 154 | static_assert(!type_list<>::contains); 155 | static_assert(!type_list<>::contains); 156 | static_assert(!type_list<>::contains); 157 | 158 | int main() 159 | { 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /tests/meson.build: -------------------------------------------------------------------------------- 1 | # This file is a part of marzer/type_list and is subject to the the terms of the MIT license. 2 | # Copyright (c) Mark Gillard 3 | # See https://github.com/marzer/type_list/blob/master/LICENSE for the full license text. 4 | # SPDX-License-Identifier: MIT 5 | 6 | test_exe = executable( 7 | 'test_exe', 8 | files('main.cpp'), 9 | dependencies: [ type_list_dep ], 10 | install: false 11 | ) 12 | 13 | test('test', test_exe) 14 | -------------------------------------------------------------------------------- /type_list.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": { 8 | "files.associations": { 9 | "type_traits": "cpp", 10 | "concepts": "cpp", 11 | "cstddef": "cpp", 12 | "cstdint": "cpp", 13 | "cstdlib": "cpp", 14 | "initializer_list": "cpp", 15 | "xstddef": "cpp", 16 | "xtr1common": "cpp", 17 | "version": "cpp", 18 | "xstring": "cpp" 19 | }, 20 | "explorer.sortOrder": "type" 21 | } 22 | } 23 | --------------------------------------------------------------------------------