{"id":18534308,"url":"https://github.com/zxshady/extra_traits","last_synced_at":"2026-01-24T00:52:56.680Z","repository":{"id":248464289,"uuid":"826106046","full_name":"ZXShady/extra_traits","owner":"ZXShady","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-05T11:35:45.000Z","size":114,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T23:51:07.567Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ZXShady.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-09T05:46:49.000Z","updated_at":"2024-10-06T00:31:56.000Z","dependencies_parsed_at":"2024-08-03T19:54:37.330Z","dependency_job_id":"a85f6337-dfac-4eb2-bb94-349c29a523a0","html_url":"https://github.com/ZXShady/extra_traits","commit_stats":null,"previous_names":["zxshady/extra_traits"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZXShady%2Fextra_traits","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZXShady%2Fextra_traits/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZXShady%2Fextra_traits/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZXShady%2Fextra_traits/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZXShady","download_url":"https://codeload.github.com/ZXShady/extra_traits/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250438531,"owners_count":21430813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T19:15:22.052Z","updated_at":"2026-01-24T00:52:56.649Z","avatar_url":"https://github.com/ZXShady.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# extra_traits\n\nsimple library for some missing type traits I always need when making unreadable meta programs.\n\nMinimum C++11 with support for variadic macros and variaidc templates and type traits library.\n\nall these are available in namespace `zxshady::tmp` and all type traits have _t unconditionally but it also has _v shortcuts if available. \n\n\nhas_operator_*\n\neach of these has their own header for minimizing includes you can look at the file names at `include/zxshady/has_operators/`\n\n| Category | Operator |\n|---|---|\n| Increment/Decrement | post_increment |\n| | pre_decrement |\n| | pre_increment |\n| | post_increment |\n| Unary | dereference |\n| | complement |\n| | unary_minus |\n| | unary_plus |\n| Bitwise | bit_and |\n| | bit_or |\n| | bit_xor |\n| | bit_and_assign |\n| | bit_or_assign |\n| | bit_xor_assign |\n| Shift | left_shift |\n| | left_shift_assign |\n| | right_shift |\n| | right_shift_assign |\n| Logical | logical_and |\n| | logical_not |\n| | logical_or |\n| Arithmetic | plus |\n| | minus |\n| | modulus |\n| | multiply |\n| | divide |\n| | plus_assign |\n| | minus_assign |\n| | modulus_assign |\n| | multiply_assign |\n| | divide_assign |\n| Comparison | equal_to |\n| | not_equal_to |\n| | less |\n| | less_equal |\n| | greater |\n| | greater_equal |\n| Accessors | arrow |\n| | subscript |\n| | addressof |\n| Functor | call |\n\neach has_operator_XXX has 4 static members\n\n```cpp\nhas_operator_XXX\u003cT\u003e::member; // whether it is a member function\nhas_operator_XXX\u003cT\u003e::free; // whether it is a free function\nhas_operator_XXX\u003cT\u003e::overloaded; // equalivent to member || free\nhas_operator_XXX\u003cT\u003e::value; // whether it has the operator or not\n```\n\nsimple type aliases\n\n```cpp\n\ntemplate\u003cstd::size_t Value\u003e\nusing index_c = std::integral_constant\u003cstd::size_t,Value\u003e;\n\ntemplate\u003ctypename T\u003e\nusing alignof_c = std::integral_constant\u003cstd::size_t,alignof(T)\u003e;\n\ntemplate\u003ctypename T\u003e\nusing sizeof_c = std::integral_constant\u003cstd::size_t,sizeof(T)\u003e;\n\n// this is avaiable in C++17\ntemplate\u003cauto Value\u003e \nusing constant = std::integral_constant\u003cdecltype(Value),Value\u003e;\n\ntemplate\u003ctypename Trait\u003e\nusing t_ = typename Trait::type; // shortcut trait\n\ntemplate\u003ctypename Trait\u003e\nconstexpr bool v_ = Trait::value; // shortcut variable\n\n_\ntemplate\u003ctypename...\u003e\nusing always_false = std::false_type; (var alias : false_v)\n\ntemplate\u003ctypename...\u003e\nusing always_true = std::true_type; (var alias: true_v)\n\ntemplate\u003ctypename T,typename...\u003e\nusing type_t = T;\n\ntemplate\u003ctypename T\u003e // since C++14\nusing is_inheritable = bool_constant\u003cstd::is_class_v\u003cT\u003e \u0026\u0026 !std::is_final_v\u003cT\u003e \u003e;\n\ntemplate\u003ctypename...\u003e\nstruct empty_base {};\n\n// does not report true for bool\ntemplate\u003ctypename T\u003e\nusing is_signed_integral = std::bool_constant\u003c\n!std::is_same_v\u003cbool,std::remove_cv_t\u003cT\u003e\u003e \u0026\u0026 std::is_integral_v\u003cT\u003e \u0026\u0026 std::is_signed_v\u003cT\u003e\u003e; \n\n\n// does not report true for bool\ntemplate\u003ctypename T\u003e\nusing is_unsigned_integral = std::bool_constant\u003c!std::is_same_v\u003cbool,std::remove_cv_t\u003cT\u003e\u003e \u0026\u0026 std::is_integral_v\u003cT\u003e \u0026\u0026 std::is_unsigned_v\u003cT\u003e\u003e; \n\n```\n\nutility functions\n\n```cpp\nas_const(T\u0026) // same as std::as__const\nas_volatile(T\u0026) \nas_cv(T\u0026)\nforward_like\u003cLike\u003e(T\u0026)\n\n\n```\n\nStandard Library Features in previous C++ versions\n```cpp\n// in \"extra_traits/standard_library_features.hpp\"\nstd::disjunction\nstd::conjunction\nstd::negation\nstd::is_null_pointer\nstd::bool_constant\nstd::type_identity\nstd::integer_sequence\nstd::remove_cvref\nstd::void_t\nstd::is_scoped_enum\nstd::is_bounded_array\nstd::is_unbounded_array\n```\n\nutility traits\n\n\n```cpp\n template\u003cbool Condition,typename Base\u003e\n inherit_if\u003cCondition,Base\u003e::type // if Condition is true then inherit from Base otherwise inherit from empty_base\u003cBase\u003e\n```\n\nnon-short circuiting `disjunction` and `conjunction`\n\n```cpp\nand_\u003cTraits...\u003e::value;\nor_\u003cTraits...\u003e::value;\n\n```\n\nconstructing predicates\n```cpp\ntemplate\u003ctemplate\u003cclass...\u003e class... Predicates\u003e\nstruct predicate_and;\n\ntemplate\u003ctemplate\u003cclass...\u003e class... Predicates\u003e\nstruct predicate_or;\n\ntemplate\u003ctemplate\u003cclass...\u003e class Predicates\u003e\nstruct predicate_not;\n\n// each one of them has a member called \n// 'invoke' that is used like this\nusing is_const_integer = predicate_and\u003cstd::is_const,std::is_integral\u003e;\nstatic_assert(template is_const_integer::invoke\u003cint\u003e::value);\n\n\n```\n\n\nunary traits\n```cpp\nis_scoped_enum\u003cEnum\u003e::value\nis_unscoped_enum\u003cEnum\u003e::value\n```\n\nmodifying traits\n```cpp\nremove_all_pointers\u003cint******\u003e -\u003e int;\nremove_all_pointers\u003cfloat(*)[]\u003e -\u003e float[];\n```\n\n## Qualifications Copying and Maniplating Traits\n\n- from [paper](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1016r0.pdf)\n\n*Note each `copy_xxxxx` trait has a corrosponding `clone_xxxxx` (except `copy_signedness` there is no corrosponding `clone_signedness`)* which is equal to `copy_xxxxx\u003cFrom,remove_xxxxx_t\u003cTo\u003e\u003e`*\n\n\n\n\u003ch3 id =\"copy_const\"\u003e\ncopy_const\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n```cpp\nFrom                  -\u003e To\nconst From            -\u003e const To\nvolatile From         -\u003e To\nconst volatile From   -\u003e const To\n--------------------------------\nFrom\u0026                 -\u003e To\nconst From\u0026           -\u003e To\nvolatile From\u0026        -\u003e To\nconst volatile From\u0026  -\u003e To\n--------------------------------\nFrom\u0026\u0026                -\u003e To\nconst From\u0026\u0026          -\u003e To\nvolatile From\u0026\u0026       -\u003e To\nconst volatile From\u0026\u0026 -\u003e To\n```\n\u003c/details\u003e  \n\n\n\u003ch3 id =\"copy_volatile\"\u003e\ncopy_volatile\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n```cpp\nFrom                  -\u003e To\nconst From            -\u003e To\nvolatile From         -\u003e volatile To\nconst volatile From   -\u003e volatile To\n--------------------------------\nFrom\u0026                 -\u003e To\nconst From\u0026           -\u003e To\nvolatile From\u0026        -\u003e To\nconst volatile From\u0026  -\u003e To\n--------------------------------\nFrom\u0026\u0026                -\u003e To\nconst From\u0026\u0026          -\u003e To\nvolatile From\u0026\u0026       -\u003e To\nconst volatile From\u0026\u0026 -\u003e To\n```\n\u003c/details\u003e  \n\n## copy_cv\u003cFrom,To\u003e\n\u003cp\u003e is a short cut for  \u003ca href=\"#copy_const\"\u003ecopy_const_t\u003c/a\u003e\n\u0026ltFrom,\u003ca href=\"#copy_volatile\"\u003ecopy_volatile_t\u003c/a\u003e\u0026ltFrom,To\u0026gt\u0026gt\n\u003c/p\u003e\n\u003cdetails\u003e\n\u003csummary\u003eShow Table\u003c/summary\u003e\nFrom                  -\u003e To\nconst From            -\u003e const To\nvolatile From         -\u003e volatile To\nconst volatile From   -\u003e const volatile To\n--------------------------------\nFrom\u0026                 -\u003e To\nconst From\u0026           -\u003e To\nvolatile From\u0026        -\u003e To\nconst volatile From\u0026  -\u003e To\n--------------------------------\nFrom\u0026\u0026                -\u003e To\nconst From\u0026\u0026          -\u003e To\nvolatile From\u0026\u0026       -\u003e To\nconst volatile From\u0026\u0026 -\u003e To\n\u003c/details\u003e\n\n\n\n\u003ch3 id =\"copy_reference\"\u003e\ncopy_reference\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n  # NOTE: this uses reference collapsing rules, which may not be wanted if you do not want it then use `clone_reference`.\n```cpp\nFrom                  -\u003e To\nconst From            -\u003e To\nvolatile From         -\u003e To\nconst volatile From   -\u003e To\n--------------------------------\nFrom\u0026                 -\u003e To\u0026\nconst From\u0026           -\u003e To\u0026\nvolatile From\u0026        -\u003e To\u0026\nconst volatile From\u0026  -\u003e To\u0026\n--------------------------------\nFrom\u0026\u0026                -\u003e To\u0026\u0026\nconst From\u0026\u0026          -\u003e To\u0026\u0026\nvolatile From\u0026\u0026       -\u003e To\u0026\u0026\nconst volatile From\u0026\u0026 -\u003e To\u0026\u0026\n```\n\u003c/details\u003e  \n\n## copy_cvref\u003cFrom,To\u003e\na short cut for \"copy_reference\u003cFrom, [copy_reference_t](#copy_reference)\u003cTo, [copy_cv_t](#copy_cv)\u003cremove_reference_t\\\u003cFrom\\\u003e, remove_reference_t\\\u003cTo\\\u003e\u003e\u003e\u003e\"\n\n\u003ch3 id =\"copy_pointer\"\u003e\ncopy_pointer\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n```cpp\nFrom                  -\u003e To\nconst From            -\u003e To\nvolatile From         -\u003e To\nconst volatile From   -\u003e To\n--------------------------------\nFrom*                 -\u003e To*\nFrom*const            -\u003e To*\nFrom*volatile         -\u003e To*\nFrom*const volatile   -\u003e To*\n```\n\u003c/details\u003e  \n\n\n\u003ch3 id =\"copy_all_pointers\"\u003e\ncopy_all_pointers\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n```cpp\nFrom                  -\u003e To\nconst From            -\u003e To\nvolatile From         -\u003e To\nconst volatile From   -\u003e To\n--------------------------------\nFrom**                 -\u003e To**\nFrom**const            -\u003e To**\nFrom**volatile         -\u003e To**\nFrom**const volatile   -\u003e To**\n```\n\u003c/details\u003e  \n\n\u003ch3 id =\"copy_signedness\"\u003e\ncopy_signedness\u0026ltFrom,To\u0026gt \n\u003c/h3\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eShow Table\u003c/summary\u003e\n  \n```cpp\nsigned From                  -\u003e signed To\nconst signed From            -\u003e signed To\nvolatile signed From         -\u003e signed To\nconst volatile signed From   -\u003e signed To\n--------------------------------\nunsigned From                  -\u003e unsigned To\nconst unsigned From            -\u003e unsigned To\nvolatile unsigned From         -\u003e unsigned To\nconst volatile unsigned From   -\u003e unsigned To\n--------------------------------\nchar                 -\u003e [to's sign does not change] To\nconst char           -\u003e [to's sign does not change] To\nvolatile char        -\u003e [to's sign does not change] To\nconst volatile char  -\u003e [to's sign does not change] To\n\n```\n\u003c/details\u003e  \n\n\n### least_size_[u]int\u003cN\u003e\n\ngets the smallest unsigned or signed integer type that can hold this value\n\n\u003cdetails\u003e\n\u003csummary\u003eShow Example (it can differ depending on the size of types)\u003c/summary\u003e\n\n\n```cpp\nleast_size_uint_t\u003c200\u003e; // unsigned char\nleast_size_int_t\u003c500\u003e; // signed short \n```\n\u003c/details\u003e\n\n\n\n\n### remove_[l|r]value_reference\n\nremoves the reference qualifier if it is an L or R value respectivly.\n\n\u003cdetails\u003e\n\u003csummary\u003eShow Table\u003c/summary\u003e\n\n\n```cpp\ntypename remove_lvalue_reference\u003cint\u003e::type; // int\ntypename remove_lvalue_reference\u003cint\u0026\u003e::type; // int\ntypename remove_lvalue_reference\u003cint\u0026\u0026\u003e::type; // int\u0026\u0026\n\ntypename remove_rvalue_reference\u003cint\u003e::type; // int\ntypename remove_rvalue_reference\u003cint\u0026\u003e::type; // int\u0026\ntypename remove_rvalue_reference\u003cint\u0026\u0026\u003e::type; // int\n\n```\n\u003c/details\u003e\n\n\n### ZXSHADY_FWD ZXSHADY_MOV macros\n\nthe first does a std::forward and the second does std::move, why does these exist? well it is for compile time performance as std::forward is relativly expensive for a glorified `static_cast` these macros fix this issue these macros are in the `extra_traits/macros.hpp` header file.\n\n\u003cdetails\u003e\n\u003csummary\u003eShow Example\u003c/summary\u003e\n\n\n```cpp\n\n[](auto\u0026\u0026 vals) {\nstd::forward\u003cdecltype(vals)\u003e(vals);\n// vs  \nZXSHADY_FWD(vals)\n\nstd::move(vals);\n// vs\nZXSHADY_MOV(vals);\n}\n\n```\n\u003c/details\u003e\n\n\u003ch3 id=\"is_explicitly_constructible\"\u003e\nis_explicitly_constructible\u003cT,Args...\u003e\n\u003c/h3\u003e\ntests for whether the type is explicitly constructible given the Args\n\n\n*it also has `is_explicitly_default_constructible\u003cT\u003e`,`is_explicitly_copy_constructible\u003cT\u003e` and `is_explicitly_move_constructible\u003cT\u003e`*\n```cpp\nusing namespace zxshady::tmp;\n\nstruct A {\n    explicit A(int,int);\n    /*implicit*/ A(int,int,int);\n};\nis_explicitly_constructible\u003cA,int,int\u003e::value; // true\nis_explicitly_constructible\u003cA,int,int,int\u003e::value; // false\nis_explicitly_constructible\u003cA,char*\u003e::value; // false\n\n```\n## is_implicitly_constructible\u003cT,Args...\u003e\n\nthe opposite of [is_explicitly_constructible\\\u003cT,Args...\\\u003e](#is_explicitly_constructible) it checks whether the type is implictly constructible\n\n*it also has `is_implicitly_default_constructible\u003cT\u003e`,`is_implicitly_copy_constructible\u003cT\u003e` and `is_implicitly_move_constructible\u003cT\u003e`*\n```cpp\nusing namespace zxshady::tmp;\n\nstruct A {\n    explicit A(int,int);\n    /*implicit*/ A(int,int,int);\n};\nis_implicitly_constructible\u003cA,int,int\u003e::value; // false\nis_implicitly_constructible\u003cA,int,int,int\u003e::value; // true\nis_implicitly_constructible\u003cA,char*\u003e::value; // false\n```\n\n\n## type_list\u003cTypes...\u003e\n\na container that contains types.\n\n## *static members*\n\u003cp id=\"size\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003esize\u003c/summary\u003e\na static constant equal to `sizeof...(Types)`\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(List::size == 3);\n```\n\u003c/details\u003e\n\n\u003cp id=\"is_empty\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eis_empty\u003c/summary\u003e\na static boolean constant equal to size == 0\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nusing List2 = type_list\u003c\u003e;\nstatic_assert(!List::is_empty);\nstatic_assert(List2::is_empty);\n```\n\u003c/details\u003e\n\n\n\u003cp id=\"at\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eat\u0026ltIndex\u0026gt\u003c/summary\u003e\nindex into the types from the list.\nif the index is out of bounds a `static_assert` will fire.\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(std::is_same_v\u003cchar,List::template at\u003c1\u003e\u003e);\n```\n\u003c/details\u003e\n\n\u003cp id=\"at_or\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eat_or\u0026ltIndex,OrType\u0026gt\u003c/summary\u003e\nindex into the types from the list. if the index is out of bounds\nthen returns the OrType instead of failing.\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(std::is_same_v\u003clong,List::template at_or\u003c2,void\u003e\u003e); \nstatic_assert(std::is_same_v\u003cvoid,List::template at_or\u003c5,void\u003e\u003e);\n```\n\u003c/details\u003e\n\n\u003cp id=\"front\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003efront\u003c/summary\u003e\nequal to `List::template at\u0026lt0\u0026gt`\n\n*note this member does not exist if is_empty is true* \n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(std::is_same_v\u003cint,List::front\u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"back\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eback\u003c/summary\u003e\nequal to `List::template at\u0026ltsize-1\u0026gt`\n\n*note this member does not exist if is_empty is true* \n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(std::is_same_v\u003clong,List::back\u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"operator_plus\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eoperator+\u003c/summary\u003e\ndoes concatenation of 2 lists\n\n```cpp\nusing List1 = type_list\u003cint[1],int[2]\u003e;\nusing List2 = type_list\u003cint[3],int[4]\u003e;\nstatic_assert(std::is_same_v\u003cdecltype(List1{} + List2{}),type_list\u0026gtint[1],int[2],int[3],int[4]\u0026lt\u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"reverse\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003ereverse\u003c/summary\u003e\nreverses the list\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nusing NewList = List::reverse;\nstatic_assert(std::is_same_v\u003clong,NewList::back\u003e); \nstatic_assert(std::is_same_v\u003cint,NewList::front\u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"pop_front\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003epop_front\u003c/summary\u003e\npops the first type in the list\n\n```cpp\nusing List = type_list\u003cint,char,unsigned int,long\u003e;\nusing NewList = List::pop_front;\nstatic_assert(std::is_same_v\u003cchar,NewList::front\u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"pop_back\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003epop_back\u003c/summary\u003e\npops the last type in the list\n\n```cpp\nusing List = type_list\u003cint,char,unsigned int,long\u003e;\nusing NewList = List::pop_back;\nstatic_assert(std::is_same_v\u003cunsigned int,NewList::back\u003e); \n```\n\u003c/details\u003e\n\n\u003cp id=\"transform\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003etransform\u0026ltTransformTrait\u0026gt\u003c/summary\u003e\napply the TransformTrait to every type in the list,\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\nstatic_assert(std::is_same_v\u003cList::template transform\u003cstd::add_const\u003e,type_list\u003cconst int,const char,const long\u003e \u003e); \n```\n\u003c/details\u003e\n\n\u003cp id=\"rename_to\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003erename_to\u0026ltTemplate\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,custom_allocator\u003cint\u003e\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template rename_to\u003cstd::vector\u003e,std::vector\u003cint,custom_allocator\u003cint\u003e\u003e \u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"insert\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003einsert\u0026ltIndex,Types...\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template insert\u003c1,unsigned int,void\u003e,type_list\u003cint,char,unsigned int ,void,long\u003e \u003e); \n```\n\u003c/details\u003e\n\n\u003cp id=\"erase\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eerase\u0026ltIndex\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,void,char\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template erase\u003c1\u003e,type_list\u003cint,char\u003e \u003e); \n```\n\u003c/details\u003e\n\n\n\u003cp id=\"erase_if\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eerase_if\u0026ltPredicate\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,const void,char,const long\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template erase_if\u003cstd::is_const\u003e,type_list\u003cint,char\u003e \u003e); \n```\n\u003c/details\u003e\n\n\u003cp id=\"slice\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003eslice\u0026ltBegin,End = size\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint[1],int[2],int[3],int[4]\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template slice\u003c0\u003e,type_list\u003cint[1],int[2],int[3],int[4]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template slice\u003c1\u003e,type_list\u003cint[2],int[3],int[4]\u003e\u003e);\nstatic_assert(std::is_same_v\u003cList::template slice\u003c1,2\u003e,type_list\u003cint[1],int[4]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template slice\u003c4\u003e\u003e,type_list\u003c\u003e\u003e); \n\n```\n\u003c/details\u003e\n\n\n\u003cp id=\"drop_first\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003edrop_first\u0026ltCount\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint[1],int[2],int[3],int[4]\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template drop_first\u003c0\u003e,type_list\u003cint[1],int[2],int[3],int[4]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template drop_first\u003c1\u003e,type_list\u003cint[2],int[3],int[4]\u003e\u003e);\nstatic_assert(std::is_same_v\u003cList::template drop_first\u003c2\u003e,type_list\u003cint[3],int[4]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template drop_first\u003c4\u003e\u003e,type_list\u003c\u003e\u003e); \n\n```\n\u003c/details\u003e\n\n\u003cp id=\"drop_last\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003edrop_last\u0026ltCount\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint[1],int[2],int[3],int[4]\u003e;\n\nstatic_assert(std::is_same_v\u003cList::template drop_last\u003c0\u003e,type_list\u003cint[1],int[2],int[3],int[4]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template drop_last\u003c1\u003e,type_list\u003cint[1],int[2],int[3]\u003e\u003e);\nstatic_assert(std::is_same_v\u003cList::template drop_last\u003c2\u003e,type_list\u003cint[1],int[2]\u003e\u003e); \nstatic_assert(std::is_same_v\u003cList::template drop_last\u003c4\u003e\u003e,type_list\u003c\u003e\u003e); \n```\n\n\u003c/details\u003e\n\n\n\u003cp id=\"replace_at\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003ereplace_at\u0026ltIndex,T\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\n\n\nstatic_assert(std::is_same_v\u003cList::template replace_at\u003c0,void\u003e, type_list\u003cvoid,char,long\u003e\u003e);\nstatic_assert(std::is_same_v\u003cList::template replace_at\u003c1,void\u003e, type_list\u003cint,void,long\u003e\u003e);\nstatic_assert(std::is_same_v\u003cList::template replace_at\u003c2,void\u003e, type_list\u003cint,char,void\u003e\u003e);\n\n```\n\u003c/details\u003e\n\n## Free Functions\n\n\u003cp id=\"find_if\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003efind_if\u0026ltPredicate,Pos = 0\u0026gt\u003c/summary\u003e\n*note* returns std::size_t(-1) on not found \n\n```cpp\nusing List = type_list\u003cint,char,const long,volatile void\u003e;\n\n\nstatic_assert(find_if\u003cstd::is_const\u003e(List{}) == 2);\nstatic_assert(find_if\u003cstd::is_void\u003e(List{}) == 3);\n\n```\n\u003c/details\u003e\n\n\n\u003cp id=\"find\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003efind\u0026ltT,Pos = 0\u0026gt\u003c/summary\u003e\n\n```cpp\nusing List = type_list\u003cint,char,long\u003e;\n\n\nstatic_assert(find\u003cvoid\u003e(List{}) == std::size_t(-1));\nstatic_assert(find\u003cchar,0\u003e(List{}) == 1);\n\n```\n\u003c/details\u003e\n\n\n\u003cp id=\"type_list_repeat_n\"\u003e\u003c/p\u003e\u003cdetails\u003e\n\u003csummary\u003etype_list_repeat_n\u0026ltN,T\u0026gt\u003c/summary\u003e\nreturns a type_list with N Ts in it\n\n\n```cpp\nstatic_assert(std::is_same_v\u003ctype_list_repeat_n\u003c5, int\u003e, type_list\u003cint, int, int, int, int\u003e\u003e);\nstatic_assert(std::is_same_v\u003ctype_list_repeat_n\u003c0, int\u003e, type_list\u003c\u003e\u003e);\nstatic_assert(std::is_same_v\u003ctype_list_repeat_n\u003c1, int\u003e, type_list\u003cint\u003e\u003e);\n```\n\u003c/details\u003e\n\n\nthere is still more methods.\n\ndocumentation incomplete...","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzxshady%2Fextra_traits","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzxshady%2Fextra_traits","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzxshady%2Fextra_traits/lists"}