├── CMakeLists.txt ├── LICENSE_1_0.txt ├── README.md ├── include ├── typical.hpp └── typical │ ├── algorithms │ ├── at.hpp │ ├── count_if.hpp │ ├── drop_front.hpp │ ├── filter.hpp │ ├── flatten.hpp │ ├── front.hpp │ ├── index_of.hpp │ ├── join.hpp │ ├── partition.hpp │ ├── reverse.hpp │ ├── size.hpp │ ├── take.hpp │ ├── transform.hpp │ └── zip.hpp │ ├── application.hpp │ ├── compose.hpp │ ├── conditional.hpp │ ├── constant.hpp │ ├── function_support.hpp │ ├── list_predicates.hpp │ ├── type_manipulation.hpp │ ├── type_predicates.hpp │ └── utilities.hpp ├── main.cpp └── tests ├── application.cpp ├── at.cpp ├── compose.cpp ├── conditional.cpp ├── constant.cpp ├── count_if.cpp ├── drop_front.cpp ├── filter.cpp ├── flatten.cpp ├── front.cpp ├── function_support.cpp ├── index_of.cpp ├── join.cpp ├── list_predicates.cpp ├── partition.cpp ├── reverse.cpp ├── size.cpp ├── take.cpp ├── transform.cpp ├── type_manipulation.cpp ├── type_predicates.cpp └── zip.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(typical) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | 6 | set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) 7 | 8 | add_library(typical INTERFACE) 9 | target_include_directories(typical INTERFACE $) 10 | target_include_directories(typical INTERFACE $/include>) 11 | 12 | if (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR} AND CMAKE_BUILD_TYPE MATCHES Debug) 13 | 14 | add_executable(tests main.cpp include/typical/constant.hpp tests/constant.cpp include/typical/conditional.hpp tests/conditional.cpp include/typical/function_support.hpp tests/function_support.cpp include/typical/compose.hpp tests/compose.cpp include/typical/type_manipulation.hpp tests/type_manipulation.cpp include/typical/application.hpp tests/application.cpp include/typical/type_predicates.hpp tests/type_predicates.cpp include/typical/list_predicates.hpp tests/list_predicates.cpp include/typical/algorithms/transform.hpp tests/transform.cpp include/typical/algorithms/join.hpp include/typical/utilities.hpp tests/join.cpp include/typical/algorithms/size.hpp tests/size.cpp include/typical/algorithms/filter.hpp tests/filter.cpp include/typical/algorithms/partition.hpp tests/partition.cpp include/typical/algorithms/drop_front.hpp tests/drop_front.cpp include/typical/algorithms/take.hpp tests/take.cpp include/typical/algorithms/count_if.hpp tests/count_if.cpp include/typical/algorithms/index_of.hpp tests/index_of.cpp include/typical/algorithms/front.hpp tests/front.cpp include/typical/algorithms/at.hpp tests/at.cpp include/typical/algorithms/reverse.hpp tests/reverse.cpp include/typical/algorithms/flatten.hpp tests/flatten.cpp include/typical/algorithms/zip.hpp tests/zip.cpp) 15 | target_link_libraries(tests PRIVATE typical) 16 | 17 | endif() -------------------------------------------------------------------------------- /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `` 2 | 3 | A highly composable type based C++ template meta programming 4 | library. 5 | 6 | This one is in its infancy. Please toy with it, report back, 7 | and contribute to it. Do not (yet) use it in production. 8 | 9 | My aim is to make it production ready, perhaps lacking in 10 | functional breadth, but not in quality, very soon. Hopefully 11 | already in January. 12 | 13 | Highlights: 14 | 15 | * Composable 16 | * C++17 17 | * Fast 18 | 19 | It is no secret that this draws heavily on the 20 | [`Kvasir::mpl`](https://github.com/kvasir-io/mpl/) library, 21 | but by adding another level of indirection for the type 22 | functions, it becomes very composable. 23 | 24 | | | | 25 | |---|------------------------------------------------------| 26 | |Q. |Why type based when [`boost::Hana`](https://boostorg.github.io/hana/) have showed the way with value oriented TMP?| 27 | |A. |Because sometimes manipulating types is exactly what you want to do. | 28 | 29 | Example: 30 | ```Cpp 31 | using t = apply_pack_to< 32 | compose< 33 | transform>, 34 | take> 35 | >, 36 | make, 37 | int,char,double,unsigned 38 | >; 39 | // t is std::tuple 40 | ``` 41 | 42 | ## Help wanted 43 | 44 | A lot of stuff is needed to make this a fully fledged TMP library. 45 | Your help is much appreciated. Some obvious things: 46 | 47 | * CI setup for many different compilers. 48 | * Improved CMake support 49 | * [Metabench](http://metaben.ch/) integration 50 | * More and better documentation 51 | * More type functions 52 | * Are the names good enough? Are there better names that should be preferred? 53 | * Optimisations. 54 | 55 | ## Convenience types 56 | 57 | * `typical::constant`. 58 | ```Cpp 59 | template 60 | struct constant { 61 | static constexpr auto value = V; 62 | }; 63 | ``` 64 | `typical::constant` is used by type functions that 65 | return a numerical or boolean result. 66 | 67 | * `typical::list` 68 | ```Cpp 69 | template 70 | struct list {}; 71 | ``` 72 | `typical::list<...>` is the default result type for all 73 | type functions that result in more than one type. 74 | 75 | ## Type functions 76 | 77 | All type functions operate on one or several types, and 78 | deliver their result to another type function. The default 79 | terminating type functions are: 80 | 81 | * `typical::identity`, used by type functions that result in 82 | one type, and expresses it in verbatim. 83 | * `typical::make`, creates a `T`. The default for 84 | type functions that result in several types is 85 | `typical::make`. 86 | 87 | Some type functions accept only one type, other accepts 88 | parameter packs. 89 | 90 | ## Convenience type functions 91 | 92 | These are here to make it easier to work with `typical`. 93 | 94 | * `apply_pack` 95 | Passes `params...` to the type function `function`, which 96 | presents its result using the default. 97 | * `apply_pack_to`, same as above, 98 | but where `result` takes the place of the default. For 99 | example, a type function that defaults to produce a 100 | `typical::list<...>` may instead produce a tuple by calling 101 | `apply_pack_to, params...>`. 102 | * `apply_list`, passes the member types of 103 | `type` to `function`. `type` can be any type-based template, 104 | not just `typical::list<...>`, but for example 105 | `std::tuple<...>`, `std::variant<...>` or a type-list 106 | from some other TMP library. 107 | * `apply_list_to`, same as above, but 108 | where `result` is used instead of the default result type. 109 | * `metamorph,T2>` instantiates a template type 110 | `T2` with the types of the `T1` instantiation. E.g. 111 | `metamorph, std::variant>` is 112 | `std::variant`. 113 | 114 | ### `typical::is_pointer` 115 | 116 | 117 | |Arity|Result type|Default continuation|Header| 118 | |-----|-----------|--------------------|------| 119 | |1 |`typical::constant<>`|`typical::identity`|``| 120 | 121 | Example: 122 | ```Cpp 123 | using t = apply_pack; // t is constant 124 | ``` 125 | 126 | Tells whether its input type is a pointer or not. 127 | 128 | ### `typical::is_reference` 129 | 130 | |Arity|Result type|Default continuation|Header| 131 | |-----|-----------|--------------------|------| 132 | |1 |`typical::constant<>`|`typical::identity`|``| 133 | 134 | Example: 135 | ```Cpp 136 | using t = apply_pack; // t is constant 137 | ``` 138 | 139 | Tells whether its input type is a reference or not. Note that 140 | both rvalue-references and lvalue-references are references. 141 | 142 | ### `typical::is_lvalue_reference` 143 | 144 | |Arity|Result type|Default continuation|Header| 145 | |-----|-----------|--------------------|------| 146 | |1 |`typical::constant<>`|`typical::identity`|``| 147 | 148 | Example: 149 | ```Cpp 150 | using t = apply_pack; // t is constant 151 | ``` 152 | 153 | Tells whether its input type is an lvalue-reference or not. 154 | 155 | ### `typical::is_rvalue_reference` 156 | 157 | |Arity|Result type|Default continuation|Header| 158 | |-----|-----------|--------------------|------| 159 | |1 |`typical::constant<>`|`typical::identity`|``| 160 | 161 | Example: 162 | ```Cpp 163 | using t = apply_pack; // t is constant 164 | ``` 165 | 166 | Tells whether its input type is an rvalue-reference or not. 167 | 168 | ### `typical::is_const` 169 | 170 | |Arity|Result type|Default continuation|Header| 171 | |-----|-----------|--------------------|------| 172 | |1 |`typical::constant<>`|`typical::identity`|``| 173 | 174 | Example: 175 | ```Cpp 176 | using t = apply_pack; // t is constant 177 | ``` 178 | 179 | Tells whether its input type is const or not. 180 | 181 | ### `typical::is_volatile` 182 | 183 | |Arity|Result type|Default continuation|Header| 184 | |-----|-----------|--------------------|------| 185 | |1 |`typical::constant<>`|`typical::identity`|``| 186 | 187 | Example: 188 | ```Cpp 189 | using t = apply_pack; // t is constant 190 | ``` 191 | 192 | Tells whether its input type is volatile or not. 193 | 194 | ### `typical::is_template>` 195 | 196 | |Arity|Result type|Default continuation|Header| 197 | |-----|-----------|--------------------|------| 198 | |1 |`typical::constant<>`|`typical::identity`|``| 199 | 200 | Example: 201 | ```Cpp 202 | using t = apply_pack, std::variant>; // t is constant 203 | using u = apply_pack, std::tuple>; // t is constant 204 | ``` 205 | 206 | Tells whether its input type is an instantiation of the searched for 207 | template type or not. 208 | 209 | ### `typical::negate` 210 | 211 | |Arity|Result type|Default continuation|Header| 212 | |-----|-----------|--------------------|------| 213 | |1 |`typical::constant<>`|`typical::identity`|``| 214 | 215 | Example: 216 | ```Cpp 217 | using t = apply_pack>, std::variant>; // t is constant 218 | using u = apply_pack>, std::tuple>; // t is constant 219 | ``` 220 | Logically inverts the result of the function. 221 | 222 | ### `typical::is_same` 223 | 224 | |Arity|Result type|Default continuation|Header| 225 | |-----|-----------|--------------------|------| 226 | |1 |`typical::constant<>`|`typical::identity`|``| 227 | 228 | Example: 229 | ```Cpp 230 | using t = apply_pack, int>; // t is constant 231 | ``` 232 | Tells whether its input type is the searched for type or not. 233 | 234 | ### `typical::add_pointer` 235 | 236 | |Arity|Result type|Default continuation|Header| 237 | |-----|-----------|--------------------|------| 238 | |1 |pointer type|`typical::identity`|``| 239 | 240 | Example: 241 | ```Cpp 242 | using t = apply_pack; // t is int* 243 | ``` 244 | 245 | Adds pointer to the input type 246 | 247 | ### `typical::add_lvalue_reference` 248 | 249 | |Arity|Result type|Default continuation|Header| 250 | |-----|-----------|--------------------|------| 251 | |1 |reference type|`typical::identity`|``| 252 | 253 | Example: 254 | ```Cpp 255 | using t = apply_pack; // t is int& 256 | ``` 257 | Adds lvalue-reference to the input type. Note that reference 258 | collapsing rules apply. 259 | 260 | 261 | ### `typical::add_rvalue_reference` 262 | 263 | |Arity|Result type|Default continuation|Header| 264 | |-----|-----------|--------------------|------| 265 | |1 |reference type|`typical::identity`|``| 266 | 267 | Example: 268 | ```Cpp 269 | using t = apply_pack; // t is int&& 270 | ``` 271 | Adds rvalue-reference to the input type. Note that reference 272 | collapsing rules apply. 273 | 274 | 275 | ### `typical::add_const` 276 | 277 | |Arity|Result type|Default continuation|Header| 278 | |-----|-----------|--------------------|------| 279 | |1 |reference type|`typical::identity`|``| 280 | 281 | Example: 282 | ```Cpp 283 | using t = apply_pack; // t is int const 284 | ``` 285 | Adds const to the input type. 286 | 287 | ### `typical::add_volatile` 288 | 289 | |Arity|Result type|Default continuation|Header| 290 | |-----|-----------|--------------------|------| 291 | |1 |reference type|`typical::identity`|``| 292 | 293 | Example: 294 | ```Cpp 295 | using t = apply_pack; // t is int volatile 296 | ``` 297 | Adds volatile to the input type. 298 | 299 | ### `typical::remove_cv` 300 | 301 | |Arity|Result type|Default continuation|Header| 302 | |-----|-----------|--------------------|------| 303 | |1 |unqualified type|`typical::identity`|``| 304 | 305 | Example: 306 | ```Cpp 307 | using t = apply_pack; // t is int 308 | ``` 309 | Removes const and/or volatile qualifiers from the input type. 310 | 311 | ### `typical::remove_cv_ref` 312 | 313 | |Arity|Result type|Default continuation|Header| 314 | |-----|-----------|--------------------|------| 315 | |1 |unqualified type|`typical::identity`|``| 316 | 317 | Example: 318 | ```Cpp 319 | using t = apply_pack; // t is int 320 | ``` 321 | Removes const and/or volatile qualifiers as well as references from the input type. 322 | 323 | ### `typical::remove_reference` 324 | 325 | |Arity|Result type|Default continuation|Header| 326 | |-----|-----------|--------------------|------| 327 | |1 |non-reference type|`typical::identity`|``| 328 | 329 | Example: 330 | ```Cpp 331 | using t = apply_pack; // t is int const 332 | ``` 333 | Removes rvalue-reference or lvalue-reference from the input type. 334 | 335 | ### `typical::is_empty` 336 | 337 | |Arity|Result type|Default continuation|Header| 338 | |-----|-----------|--------------------|------| 339 | |1 |typical::constant<>|`typical::identity`|``| 340 | 341 | Example: 342 | ```Cpp 343 | using t = apply_pack>; // t is constant 344 | using f = apply_pack>; // f is constant 345 | ``` 346 | Tells whether a variadic template type is instantiated with types or not. 347 | 348 | ### `typical::any_of

` 349 | 350 | |Arity|Result type|Default continuation|Header| 351 | |-----|-----------|--------------------|------| 352 | |n |typical::constant<>|`typical::identity`|``| 353 | 354 | Example: 355 | ```Cpp 356 | using t = apply_pack, int, void*, char>; // t is constant 357 | using f = apply_pack, int, void*, char>; // f is constant 358 | ``` 359 | Tells whether any of the types provided matches the predicate `P` 360 | 361 | ### `typical::all_of

` 362 | 363 | |Arity|Result type|Default continuation|Header| 364 | |-----|-----------|--------------------|------| 365 | |n |typical::constant<>|`typical::identity`|``| 366 | 367 | Example: 368 | ```Cpp 369 | using t = apply_pack, int*, void*, char*>; // t is constant 370 | using t = apply_pack, int, void*, char>; // f is constant 371 | ``` 372 | Tells whether all of the types provided matches the predicate `P` 373 | 374 | ### `typical::none_of

` 375 | 376 | |Arity|Result type|Default continuation|Header| 377 | |-----|-----------|--------------------|------| 378 | |n |typical::constant<>|`typical::identity`|``| 379 | 380 | Example: 381 | ```Cpp 382 | using t = apply_pack, int, void, char>; // t is constant 383 | using t = apply_pack, int, void*, char>; // f is constant 384 | ``` 385 | Tells whether none of the types provided matches the predicate `P` 386 | 387 | ### `typical::has` 388 | 389 | |Arity|Result type|Default continuation|Header| 390 | |-----|-----------|--------------------|------| 391 | |n |typical::constant<>|`typical::identity`|``| 392 | 393 | Example: 394 | ```Cpp 395 | using t = apply_pack, int, void, char>; // t is constant 396 | using t = apply_pack, long, void*, char>; // f is constant 397 | ``` 398 | Tells the type list provided has the searched for type. 399 | 400 | 401 | ### `typical::all_unique` 402 | 403 | |Arity|Result type|Default continuation|Header| 404 | |-----|-----------|--------------------|------| 405 | |n |typical::constant<>|`typical::identity`|``| 406 | 407 | Example: 408 | ```Cpp 409 | using t = apply_pack; // t is constant 410 | using t = apply_pack; // f is constant 411 | ``` 412 | Tells the type list provided has only unique types without duplicates. 413 | 414 | ### `typical::at` 415 | 416 | |Arity|Result type|Default continuation|Header| 417 | |-----|-----------|--------------------|------| 418 | |n |type|`typical::identity`|``| 419 | 420 | Example: 421 | ```Cpp 422 | using t = apply_pack>, int, void, char>; // t is void 423 | ``` 424 | Results in the n-th type in the parameter pack. The index can 425 | be any type that has an integral `value` member, e.g. 426 | `typical::constant` or `std::integral_constant` 427 | 428 | ### `typical::count_if` 429 | 430 | |Arity|Result type|Default continuation|Header| 431 | |-----|-----------|--------------------|------| 432 | |n |`typical::constant<>`|`typical::identity`|``| 433 | 434 | Example: 435 | ```Cpp 436 | using t = apply_pack, int, void, char const, double>; // t is constant<1> 437 | ``` 438 | Counts the number of parameters in the pack that matches the predicate. 439 | 440 | ### `typical::drop_front` 441 | 442 | |Arity|Result type|Default continuation|Header| 443 | |-----|-----------|--------------------|------| 444 | |n |list|`typical::make`|``| 445 | 446 | Example: 447 | ```Cpp 448 | using t = apply_pack>, int, void, char const, double>; // t is list 449 | ``` 450 | Drops the first N parameters from the input pack. The index 451 | type can be any type that has an integral `value` member, e.g. 452 | `typical::constant` or `std::integral_constant`. 453 | 454 | ### `typical::filter` 455 | 456 | |Arity|Result type|Default continuation|Header| 457 | |-----|-----------|--------------------|------| 458 | |n |list|`typical::make`|``| 459 | 460 | Example: 461 | ```Cpp 462 | using t = apply_pack, int, void*, char*, double>; // t is list 463 | ``` 464 | Produces a list of the types that matches the predicate. 465 | 466 | ### `typical::flatten` 467 | 468 | |Arity|Result type|Default continuation|Header| 469 | |-----|-----------|--------------------|------| 470 | |1 |list|`typical::make`|``| 471 | 472 | Example: 473 | ```Cpp 474 | using t = apply_pack,tuple>; // t is list,double> 475 | ``` 476 | Flattens the hierarchy described by the input template type. 477 | All instantiations of the same basic template are flattened, 478 | whereas instantiations of other templates are untouched. 479 | 480 | ### `typical::front` 481 | 482 | |Arity|Result type|Default continuation|Header| 483 | |-----|-----------|--------------------|------| 484 | |n |type|`typical::identity`|``| 485 | 486 | Example: 487 | ```Cpp 488 | using t = apply_pack; // t is int 489 | ``` 490 | Produces the first type in the parameter pack 491 | 492 | ### `typical::index_of` 493 | 494 | |Arity|Result type|Default continuation|Header| 495 | |-----|-----------|--------------------|------| 496 | |n |`typical::constant<>`|`typical::identity`|``| 497 | 498 | Example: 499 | ```Cpp 500 | using t = apply_pack, int,char,double>; // t is constant<1> 501 | ``` 502 | Tells the position of the searched for type in the parameter pack, 503 | or -1 if not found. 504 | 505 | ### `typical::join` 506 | 507 | |Arity|Result type|Default continuation|Header| 508 | |-----|-----------|--------------------|------| 509 | |n |list|`typical::make`|``| 510 | 511 | Example: 512 | ```Cpp 513 | using t = apply_pack,tuple>; // t is list 514 | ``` 515 | Joins members of like variadic templates. 516 | 517 | ### `typical::partition` 518 | 519 | |Arity|Result type|Default continuation|Header| 520 | |-----|-----------|--------------------|------| 521 | |n |list|`typical::make`|``| 522 | 523 | Example: 524 | ```Cpp 525 | using t = apply_pack_to, make, int,char*,unsigned*,double>; // t is tuple,list> 526 | ``` 527 | Partitions the input parameter pack acording to the predicate. Each partition is always 528 | represented by a `typical::list`, but the top-level type depends on 529 | the continuation. 530 | 531 | ### `typical::reverse` 532 | 533 | |Arity|Result type|Default continuation|Header| 534 | |-----|-----------|--------------------|------| 535 | |n |list|`typical::make`|``| 536 | 537 | Example: 538 | ```Cpp 539 | using t = apply_pack; // t is list 540 | ``` 541 | Presents the input parameter pack in reversed order 542 | 543 | ### `typical::size` 544 | 545 | |Arity|Result type|Default continuation|Header| 546 | |-----|-----------|--------------------|------| 547 | |n |`typical::constant<>`|`typical::identity`|``| 548 | 549 | Example: 550 | ```Cpp 551 | using t = apply_pack; // t is constant<4> 552 | ``` 553 | Presents number of parameters in the input pack 554 | 555 | ### `typical::take` 556 | 557 | |Arity|Result type|Default continuation|Header| 558 | |-----|-----------|--------------------|------| 559 | |n |list|`typical::make`|``| 560 | 561 | Example: 562 | ```Cpp 563 | using t = apply_pack>, int,char,unsigned,double>; // t is list 564 | ``` 565 | Takes the first N parameters from the input pack. The index 566 | type can be any type that has an integral `value` member, e.g. 567 | `typical::constant` or `std::integral_constant`. 568 | 569 | ### `typical::transform` 570 | 571 | |Arity|Result type|Default continuation|Header| 572 | |-----|-----------|--------------------|------| 573 | |n |list|`typical::make`|``| 574 | 575 | Example: 576 | ```Cpp 577 | using t = apply_pack, int,char,unsigned>; // t is list 578 | ``` 579 | Instantiates a template with the type function applied to each member 580 | of the input parameter pack. 581 | 582 | ### `typical::zip` 583 | 584 | |Arity|Result type|Default continuation|Header| 585 | |-----|-----------|--------------------|------| 586 | |2 |list|`typical::make`|``| 587 | 588 | Example: 589 | ```Cpp 590 | struct make_pair 591 | { 592 | using continuation = typical::identity; 593 | template 594 | struct to { 595 | template 596 | using result = typename C::template result>; 597 | }; 598 | }; 599 | using t = apply_pack, list,list>; // t is list,pair> 600 | ``` 601 | Instantiates a template with the result of applying the provided binary 602 | type function to the element-wise pairs of the two input lists. 603 | N.B. The inputs need not be `typical::list<>`, but must both be 604 | instantiations of variadic templates with the same number of type 605 | parameters. 606 | 607 | ### `typical::compose` 608 | 609 | |Arity|Result type|Default continuation|Header| 610 | |-----|-----------|--------------------|------| 611 | |n |-|-|``| 612 | 613 | Example: 614 | ```Cpp 615 | using t = apply_pack>,take>>,int,char,double,unsigned> // t is list 616 | ``` 617 | 618 | Create a composition of type functions that applies each of them 619 | with the result from the other. They are applied right to left. 620 | -------------------------------------------------------------------------------- /include/typical.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_TYPICAL_HPP 16 | #define TYPICAL_TYPICAL_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | namespace typical { 45 | 46 | template 47 | using identity_t = apply_one; 48 | 49 | template 50 | struct identity_template; 51 | 52 | template class L, typename ... Ts> 53 | struct identity_template> : make { 54 | }; 55 | 56 | 57 | } 58 | 59 | #endif //TYPICAL_TYPICAL_HPP 60 | -------------------------------------------------------------------------------- /include/typical/algorithms/at.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_AT_HPP 16 | #define TYPICAL_AT_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace typical 24 | { 25 | template 26 | struct at 27 | { 28 | using continuation = identity; 29 | template 30 | struct to { 31 | using TO = detail::to; 32 | template 33 | using result = apply_pack_to>, TO, Ts...>; 34 | }; 35 | }; 36 | } 37 | #endif //TYPICAL_AT_HPP 38 | -------------------------------------------------------------------------------- /include/typical/algorithms/count_if.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_COUNT_IF_HPP 16 | #define TYPICAL_COUNT_IF_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | template 24 | struct count_if { 25 | using continuation = identity; 26 | template 27 | struct to { 28 | using TO = detail::to; 29 | 30 | template 31 | static constexpr auto sum = (0 + ... + Is); 32 | 33 | template 34 | using eval = apply_pack; 35 | template 36 | using result = typename TO::template result::value...>>>; 37 | }; 38 | }; 39 | 40 | } 41 | #endif //TYPICAL_COUNT_IF_HPP 42 | -------------------------------------------------------------------------------- /include/typical/algorithms/drop_front.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018,2019 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_DROP_FRONT_HPP 16 | #define TYPICAL_DROP_FRONT_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | namespace detail { 24 | template 25 | using make_voidptr = void*; 26 | 27 | template 28 | struct drop_front_helper 29 | { 30 | template struct inner; 31 | template 32 | struct inner> 33 | { 34 | template 35 | static typename TO::template result func(make_voidptr..., detail::proxy *...); 36 | }; 37 | template 38 | using type = decltype(inner>::func(static_cast*>(nullptr)...)); 39 | }; 40 | 41 | template 42 | struct drop_front_helper 43 | { 44 | template 45 | using type = typename TO::template result; 46 | }; 47 | 48 | template 49 | struct drop_front_helper 50 | { 51 | template 52 | static typename TO::template result func(void*, detail::proxy*...); 53 | template 54 | using type = decltype(func(static_cast*>(nullptr)...)); 55 | }; 56 | 57 | template 58 | struct drop_front_helper 59 | { 60 | template 61 | static typename TO::template result func(void*, void*, detail::proxy*...); 62 | template 63 | using type = decltype(func(static_cast*>(nullptr)...)); 64 | }; 65 | 66 | template 67 | struct drop_front_helper 68 | { 69 | template 70 | static typename TO::template result func(void*, void*, void*, detail::proxy*...); 71 | template 72 | using type = decltype(func(static_cast*>(nullptr)...)); 73 | }; 74 | 75 | template 76 | struct drop_front_helper 77 | { 78 | template 79 | static typename TO::template result func(void*, void*, void*, void*, detail::proxy*...); 80 | template 81 | using type = decltype(func(static_cast*>(nullptr)...)); 82 | }; 83 | 84 | template 85 | struct drop_front_helper 86 | { 87 | template 88 | static typename TO::template result func(void*, void*, void*, void*, void*, detail::proxy*...); 89 | template 90 | using type = decltype(func(static_cast*>(nullptr)...)); 91 | }; 92 | 93 | template 94 | struct drop_front_helper 95 | { 96 | template 97 | static typename TO::template result func(void*, void*, void*, void*, void*, void*, detail::proxy*...); 98 | template 99 | using type = decltype(func(static_cast*>(nullptr)...)); 100 | }; 101 | 102 | template 103 | struct drop_front_helper 104 | { 105 | template 106 | static typename TO::template result func(void*, void*, void*, void*, void*, void*, void*, detail::proxy*...); 107 | template 108 | using type = decltype(func(static_cast*>(nullptr)...)); 109 | }; 110 | 111 | template 112 | struct drop_front_helper 113 | { 114 | template 115 | static typename TO::template result 116 | func(void*, void*, void*, void*, void*, void*, void*, void*, detail::proxy*...); 117 | template 118 | using type = decltype(func(static_cast*>(nullptr)...)); 119 | }; 120 | 121 | template 122 | struct drop_front_helper 123 | { 124 | template 125 | static typename TO::template result 126 | func(void*, void*, void*, void*, void*, void*, void*, void*, 127 | void*, detail::proxy*...); 128 | template 129 | using type = decltype(func(static_cast*>(nullptr)...)); 130 | }; 131 | 132 | template 133 | struct drop_front_helper 134 | { 135 | template 136 | static typename TO::template result 137 | func(void*, void*, void*, void*, void*, void*, void*, void*, 138 | void*, void*, detail::proxy*...); 139 | template 140 | using type = decltype(func(static_cast*>(nullptr)...)); 141 | }; 142 | 143 | template 144 | struct drop_front_helper 145 | { 146 | template 147 | static typename TO::template result 148 | func(void*, void*, void*, void*, void*, void*, void*, void*, 149 | void*, void*, void*, detail::proxy*...); 150 | template 151 | using type = decltype(func(static_cast*>(nullptr)...)); 152 | }; 153 | 154 | template 155 | struct drop_front_helper 156 | { 157 | template 158 | static typename TO::template result 159 | func(void*, void*, void*, void*, void*, void*, void*, void*, 160 | void*, void*, void*, void*, detail::proxy*...); 161 | template 162 | using type = decltype(func(static_cast*>(nullptr)...)); 163 | }; 164 | 165 | template 166 | struct drop_front_helper 167 | { 168 | template 169 | static typename TO::template result 170 | func(void*, void*, void*, void*, void*, void*, void*, void*, 171 | void*, void*, void*, void*, void*, detail::proxy*...); 172 | template 173 | using type = decltype(func(static_cast*>(nullptr)...)); 174 | }; 175 | 176 | template 177 | struct drop_front_helper 178 | { 179 | template 180 | static typename TO::template result 181 | func(void*, void*, void*, void*, void*, void*, void*, void*, 182 | void*, void*, void*, void*, void*, void*, detail::proxy*...); 183 | template 184 | using type = decltype(func(static_cast*>(nullptr)...)); 185 | }; 186 | 187 | template 188 | struct drop_front_helper 189 | { 190 | template 191 | static typename TO::template result 192 | func(void*, void*, void*, void*, void*, void*, void*, void*, 193 | void*, void*, void*, void*, void*, void*, void*, 194 | detail::proxy*...); 195 | template 196 | using type = decltype(func(static_cast*>(nullptr)...)); 197 | }; 198 | template 199 | struct drop_front_helper 200 | { 201 | template 202 | static typename TO::template result 203 | func(void*, void*, void*, void*, void*, void*, void*, void*, 204 | void*, void*, void*, void*, void*, void*, void*, void*, 205 | detail::proxy*...); 206 | template 207 | using type = decltype(func(static_cast*>(nullptr)...)); 208 | }; 209 | 210 | } 211 | 212 | template 213 | struct drop_front 214 | { 215 | using continuation = make; 216 | template 217 | struct to { 218 | using TO = detail::to; 219 | 220 | template 221 | using result = typename detail::drop_front_helper::template type; 222 | }; 223 | }; 224 | 225 | } 226 | #endif //TYPICAL_DROP_FRONT_HPP 227 | -------------------------------------------------------------------------------- /include/typical/algorithms/filter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_FILTER_HPP 16 | #define TYPICAL_FILTER_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | namespace typical 23 | { 24 | 25 | template 26 | struct filter 27 | { 28 | using continuation = make; 29 | template 30 | struct to { 31 | using TO = detail::to; 32 | template 33 | using result = typename join::template to::template result::value, list, list<>>...>; 34 | }; 35 | }; 36 | 37 | } 38 | #endif //TYPICAL_FILTER_HPP 39 | -------------------------------------------------------------------------------- /include/typical/algorithms/flatten.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_FLATTEN_HPP 16 | #define TYPICAL_FLATTEN_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace typical 23 | { 24 | struct flatten 25 | { 26 | using continuation = make; 27 | template 28 | struct to { 29 | using TO = detail::to; 30 | template 31 | struct helper; 32 | template class L, typename ... Ts> 33 | struct helper> { 34 | template 35 | struct split { 36 | using type = apply_one; 37 | }; 38 | template 39 | struct split> { 40 | using type = apply_pack_to::type...>; 41 | }; 42 | using type = apply_pack_to::type...>; 43 | }; 44 | template 45 | using result = typename helper::type; 46 | }; 47 | }; 48 | 49 | } 50 | #endif //TYPICAL_FLATTEN_HPP 51 | -------------------------------------------------------------------------------- /include/typical/algorithms/front.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_FRONT_HPP 16 | #define TYPICAL_FRONT_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | struct front { 24 | using continuation = identity; 25 | template 26 | struct to { 27 | using TO = detail::to; 28 | template 29 | static apply_one func(detail::proxy *, ...); 30 | 31 | template 32 | using result = decltype(func(static_cast *>(nullptr)...)); 33 | }; 34 | }; 35 | 36 | 37 | 38 | } 39 | #endif //TYPICAL_FRONT_HPP 40 | -------------------------------------------------------------------------------- /include/typical/algorithms/index_of.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_INDEX_OF_HPP 16 | #define TYPICAL_INDEX_OF_HPP 17 | 18 | #include 19 | #include 20 | 21 | // TODO: Requires that the searched for type only exists once. Fix that! 22 | 23 | namespace typical 24 | { 25 | template 26 | struct index_of 27 | { 28 | template 29 | static constexpr auto index_func(std::index_sequence, detail::proxy*...) 30 | { 31 | constexpr auto i = (((std::is_same_v*(Is+1)) + ... + 0)); 32 | return int(i)-1; 33 | } 34 | template 35 | static constexpr auto index_func(detail::proxy*... p) 36 | { 37 | return index_func(std::index_sequence_for{}, p...); 38 | } 39 | 40 | using continuation = identity; 41 | template 42 | struct to { 43 | using TO = detail::to; 44 | 45 | template 46 | using result = apply_one*>(nullptr)...)>>; 47 | }; 48 | }; 49 | 50 | } 51 | #endif //TYPICAL_INDEX_OF_HPP 52 | -------------------------------------------------------------------------------- /include/typical/algorithms/join.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_JOIN_HPP 16 | #define TYPICAL_JOIN_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | struct join { 24 | using continuation = make; 25 | template 26 | struct to { 27 | using TO = detail::to; 28 | template 29 | struct helper { 30 | using type = typename TO::template result<>; 31 | }; 32 | 33 | template class L, typename ... Ts> 34 | struct helper<0, L> { 35 | using type = typename TO::template result; 36 | }; 37 | template class L, typename ...T1s, typename ... T2s> 38 | struct helper<0, L, L> { 39 | using type = typename TO::template result; 40 | }; 41 | template class L, typename ...T1s, typename ...T2s, typename ... Tail> 42 | struct helper<1, L, L, Tail...> { 43 | using type = typename helper, Tail...>::type; 45 | }; 46 | template class L, typename ...T1s, typename ...T2s, typename ...T3s, typename ...T4s, typename ... Tail> 47 | struct helper<2, L, L, L, L, Tail...> { 48 | using type = typename helper, Tail...>::type; 50 | }; 51 | template class L, typename ...T1s, typename ...T2s, typename ...T3s, typename ...T4s, 52 | typename ...T5s, typename ...T6s, typename...T7s, typename ...T8s, typename ... Tail> 53 | struct helper<3, L, L, L, L, L, L, L, L, 54 | Tail...> { 55 | using type = typename helper, Tail...>::type; 57 | }; 58 | template class L, 59 | typename ...T1s, typename ...T2s, typename ...T3s, typename ...T4s, 60 | typename ...T5s, typename ...T6s, typename... T7s, typename ...T8s, 61 | typename ...T9s, typename ...T10s, typename...T11s, typename ...T12s, 62 | typename ...T13s, typename ...T14s, typename...T15s, typename ...T16s, typename ... Tail> 63 | struct helper<4, L, L, L, L, L, L, L, L, 64 | L, L, L, L, L, L, L, L, 65 | Tail...> { 66 | using type = typename helper, Tail...>::type; 68 | }; 69 | template class L, 70 | typename ...T1s, typename ...T2s, typename ...T3s, typename ...T4s, 71 | typename ...T5s, typename ...T6s, typename... T7s, typename ...T8s, 72 | typename ...T9s, typename ...T10s, typename...T11s, typename ...T12s, 73 | typename ...T13s, typename ...T14s, typename...T15s, typename ...T16s, 74 | typename ...T17s, typename ...T18s, typename...T19s, typename ...T20s, 75 | typename ...T21s, typename ...T22s, typename...T23s, typename ...T24s, 76 | typename ...T25s, typename ...T26s, typename...T27s, typename ...T28s, 77 | typename ...T29s, typename ...T30s, typename...T31s, typename ...T32s, 78 | typename ... Tail> 79 | struct helper<5, L, L, L, L, L, L, L, L, 80 | L, L, L, L, L, L, L, L, 81 | L, L, L, L, L, L, L, L, 82 | L, L, L, L, L, L, L, L, 83 | Tail...> { 84 | using type = typename helper, Tail...>::type; 86 | }; 87 | template class L, 88 | typename ...T1s, typename ...T2s, typename ...T3s, typename ...T4s, 89 | typename ...T5s, typename ...T6s, typename... T7s, typename ...T8s, 90 | typename ...T9s, typename ...T10s, typename...T11s, typename ...T12s, 91 | typename ...T13s, typename ...T14s, typename...T15s, typename ...T16s, 92 | typename ...T17s, typename ...T18s, typename...T19s, typename ...T20s, 93 | typename ...T21s, typename ...T22s, typename...T23s, typename ...T24s, 94 | typename ...T25s, typename ...T26s, typename...T27s, typename ...T28s, 95 | typename ...T29s, typename ...T30s, typename...T31s, typename ...T32s, 96 | typename ...T33s, typename ...T34s, typename...T35s, typename ...T36s, 97 | typename ...T37s, typename ...T38s, typename...T39s, typename ...T40s, 98 | typename ...T41s, typename ...T42s, typename...T43s, typename ...T44s, 99 | typename ...T45s, typename ...T46s, typename...T47s, typename ...T48s, 100 | typename ...T49s, typename ...T50s, typename...T51s, typename ...T52s, 101 | typename ...T53s, typename ...T54s, typename...T55s, typename ...T56s, 102 | typename ...T57s, typename ...T58s, typename ...T59s, typename ...T60s, 103 | typename ...T61s, typename ...T62s, typename ...T63s, typename ...T64s, 104 | typename ... Tail> 105 | struct helper<6, L, L, L, L, L, L, L, L, 106 | L, L, L, L, L, L, L, L, 107 | L, L, L, L, L, L, L, L, 108 | L, L, L, L, L, L, L, L, 109 | L, L, L, L, L, L, L, L, 110 | L, L, L, L, L, L, L, L, 111 | L, L, L, L, L, L, L, L, 112 | L, L, L, L, L, L, L, L, 113 | Tail...> { 114 | using type = typename helper, Tail...>::type; 116 | }; 117 | template class L, 118 | typename ...T1s, typename ...T2s, typename ... T3s, typename ...T4s, 119 | typename ...T5s, typename ...T6s, typename ... T7s, typename ...T8s, 120 | typename ...T9s, typename ...T10s, typename ...T11s, typename ...T12s, 121 | typename ...T13s, typename ...T14s, typename ...T15s, typename ...T16s, 122 | typename ...T17s, typename ...T18s, typename ...T19s, typename ...T20s, 123 | typename ...T21s, typename ...T22s, typename ...T23s, typename ...T24s, 124 | typename ...T25s, typename ...T26s, typename ...T27s, typename ...T28s, 125 | typename ...T29s, typename ...T30s, typename ...T31s, typename ...T32s, 126 | typename ...T33s, typename ...T34s, typename ...T35s, typename ...T36s, 127 | typename ...T37s, typename ...T38s, typename ...T39s, typename ...T40s, 128 | typename ...T41s, typename ...T42s, typename ...T43s, typename ...T44s, 129 | typename ...T45s, typename ...T46s, typename ...T47s, typename ...T48s, 130 | typename ...T49s, typename ...T50s, typename ...T51s, typename ...T52s, 131 | typename ...T53s, typename ...T54s, typename ...T55s, typename ...T56s, 132 | typename ...T57s, typename ...T58s, typename ...T59s, typename ...T60s, 133 | typename ...T61s, typename ...T62s, typename ...T63s, typename ...T64s, 134 | typename ...T65s, typename ...T66s, typename ...T67s, typename ...T68s, 135 | typename ...T69s, typename ...T70s, typename ...T71s, typename ...T72s, 136 | typename ...T73s, typename ...T74s, typename ...T75s, typename ...T76s, 137 | typename ...T77s, typename ...T78s, typename ...T79s, typename ...T80s, 138 | typename ...T81s, typename ...T82s, typename ...T83s, typename ...T84s, 139 | typename ...T85s, typename ...T86s, typename ...T87s, typename ...T88s, 140 | typename ...T89s, typename ...T90s, typename ...T91s, typename ...T92s, 141 | typename ...T93s, typename ...T94s, typename ...T95s, typename ...T96s, 142 | typename ...T97s, typename ...T98s, typename ...T99s, typename ...T100s, 143 | typename ...T101s, typename ...T102s, typename ...T103s, typename ...T104s, 144 | typename ...T105s, typename ...T106s, typename ...T107s, typename ...T108s, 145 | typename ...T109s, typename ...T110s, typename ...T111s, typename ...T112s, 146 | typename ...T113s, typename ...T114s, typename ...T115s, typename ...T116s, 147 | typename ...T117s, typename ...T118s, typename ...T119s, typename ...T120s, 148 | typename ...T121s, typename ...T122s, typename ...T123s, typename ...T124s, 149 | typename ...T125s, typename ...T126s, typename ...T127s, typename ...T128s, 150 | typename ... Tail> 151 | struct helper, L, L, L, L, L, L, L, 152 | L, L, L, L, L, L, L, L, 153 | L, L, L, L, L, L, L, L, 154 | L, L, L, L, L, L, L, L, 155 | L, L, L, L, L, L, L, L, 156 | L, L, L, L, L, L, L, L, 157 | L, L, L, L, L, L, L, L, 158 | L, L, L, L, L, L, L, L, 159 | L, L, L, L, L, L, L, L, 160 | L, L, L, L, L, L, L, L, 161 | L, L, L, L, L, L, L, L, 162 | L, L, L, L, L, L, L, L, 163 | L, L, L, L, L, L, L, L, 164 | L, L, L, L, L, L, L, L, 165 | L, L, L, L, L, L, L, L, 166 | L, L, L, L, L, L, L, L, 167 | L, Tail...> { 168 | using type = typename helper, Tail...>::type; 170 | }; 171 | template 172 | using result = typename helper::type; 173 | }; 174 | }; 175 | 176 | } 177 | #endif //TYPICAL_JOIN_HPP 178 | -------------------------------------------------------------------------------- /include/typical/algorithms/partition.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_PARTITION_HPP 16 | #define TYPICAL_PARTITION_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace typical 24 | { 25 | template 26 | struct partition { 27 | using continuation = make; 28 | template 29 | struct to { 30 | using TO = detail::to; 31 | template 32 | struct helper { 33 | using type = typename TO::template result, conditional_t::value, list, list<>>...>, 34 | apply_pack_to, conditional_t::value, list<>, list>...>>; 35 | }; 36 | template 37 | using result = typename helper::type; 38 | }; 39 | }; 40 | 41 | } 42 | #endif //TYPICAL_PARTITION_HPP 43 | -------------------------------------------------------------------------------- /include/typical/algorithms/reverse.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_REVERSE_HPP 16 | #define TYPICAL_REVERSE_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | // TODO: This naive implementation is super slow! 23 | 24 | namespace typical 25 | { 26 | struct reverse { 27 | using continuation = make; 28 | template 29 | struct to { 30 | using TO = detail::to; 31 | template 32 | struct helper; 33 | 34 | template class L, typename ... Ts> 35 | struct helper<0, L, false> { 36 | using type = L; 37 | }; 38 | template class L, typename T, typename ... Ts> 39 | struct helper<1, L, false> { 40 | using type = L; 41 | }; 42 | template class L, typename T1, typename T2, typename ... Ts> 43 | struct helper<2, L, false> { 44 | using type = L; 45 | }; 46 | template class L, typename T1, typename T2, typename T3, typename ... Ts> 47 | struct helper<3, L, false> { 48 | using type = L; 49 | }; 50 | template class L, typename T1, typename T2, typename T3, typename T4, typename ... Ts> 51 | struct helper<4, L, false> { 52 | using type = L; 53 | }; 54 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename ... Ts> 55 | struct helper<5, L, false> { 56 | using type = L; 57 | }; 58 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename ... Ts> 59 | struct helper<6, L, false> { 60 | using type = L; 61 | }; 62 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename ... Ts> 63 | struct helper<7, L, false> { 64 | using type = L; 65 | }; 66 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename ... Ts> 67 | struct helper<8, L, false> { 68 | using type = L; 69 | }; 70 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename ... Ts> 71 | struct helper<9, L, false> { 72 | using type = L; 73 | }; 74 | template class L, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename ... Ts> 75 | struct helper, true> { 76 | using type = apply_pack_to, (N >= 20)>::type, L>; 78 | }; 79 | template 80 | using result = typename helper, (sizeof...(T) >= 10)>::type; 81 | }; 82 | }; 83 | 84 | } 85 | #endif //TYPICAL_REVERSE_HPP 86 | -------------------------------------------------------------------------------- /include/typical/algorithms/size.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_SIZE_HPP 16 | #define TYPICAL_SIZE_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | struct size { 24 | template 25 | struct helper; 26 | template class L, typename ... Ts> 27 | struct helper> { 28 | static constexpr std::size_t value = sizeof...(Ts); 29 | }; 30 | using continuation = identity; 31 | template 32 | struct to { 33 | using TO = detail::to; 34 | template 35 | using result = apply_one::value>>; 36 | }; 37 | }; 38 | 39 | } 40 | #endif //TYPICAL_SIZE_HPP 41 | -------------------------------------------------------------------------------- /include/typical/algorithms/take.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_TAKE_HPP 16 | #define TYPICAL_TAKE_HPP 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace typical 23 | { 24 | template 25 | struct take 26 | { 27 | using continuation = make; 28 | template 29 | struct to { 30 | using TO = detail::to; 31 | 32 | template 33 | struct helper; 34 | 35 | template 36 | struct helper<0, 0, false, Ts...> { 37 | using type = list<>; 38 | }; 39 | 40 | template 41 | struct helper<1, 0, false, T, Ts...> { 42 | using type = list; 43 | }; 44 | template 45 | struct helper { 46 | using type = apply_pack, typename helper< 47 | I - 2, detail::log2(I - 2), false, Ts...>::type>; 48 | }; 49 | template 50 | struct helper { 51 | using type = apply_pack, typename helper< 52 | I - 4, detail::log2(I - 4), false, Ts...>::type>; 53 | }; 54 | template 58 | struct helper { 59 | using type = apply_pack, typename helper< 60 | I - 8, detail::log2(I - 8), false, Ts...>::type>; 61 | }; 62 | template 68 | struct helper { 69 | using type = apply_pack, typename helper< 70 | I - 16, detail::log2(I - 16), (I >= 32), Ts...>::type>; 71 | }; 72 | template 73 | using result = apply_pack_to 15), Ts...>::type>; 75 | }; 76 | }; 77 | 78 | } 79 | #endif //TYPICAL_TAKE_HPP 80 | -------------------------------------------------------------------------------- /include/typical/algorithms/transform.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_TRANSFORM_HPP 16 | #define TYPICAL_TRANSFORM_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | template 24 | struct transform { 25 | using fto = typename F::template to<>; 26 | using continuation = make; 27 | template 28 | struct to { 29 | using TO = detail::to; 30 | template 31 | using result = typename TO::template result...>; 32 | }; 33 | }; 34 | 35 | } 36 | 37 | #endif //TYPICAL_TRANSFORM_HPP 38 | -------------------------------------------------------------------------------- /include/typical/algorithms/zip.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_ZIP_HPP 16 | #define TYPICAL_ZIP_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | template 24 | struct zip { 25 | using continuation = make; 26 | template 27 | struct to { 28 | using TO = detail::to; 29 | template 30 | struct helper; 31 | template class L1, typename ... L1s, 32 | template class L2, typename ... L2s> 33 | struct helper, L2> { 34 | using type = typename TO::template result< apply_pack...>; 35 | }; 36 | template 37 | using result = typename helper::type; 38 | }; 39 | }; 40 | 41 | } 42 | #endif //TYPICAL_ZIP_HPP 43 | -------------------------------------------------------------------------------- /include/typical/application.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_APPLICATION_HPP 16 | #define TYPICAL_APPLICATION_HPP 17 | 18 | #include 19 | #include 20 | 21 | namespace typical 22 | { 23 | struct unwrap { 24 | using continuation = make; 25 | template 26 | struct to { 27 | using TO = detail::to; 28 | template 29 | struct helper { 30 | using type = typename TO::template result; 31 | }; 32 | template class L, typename... Ts> 33 | struct helper> { 34 | using type = typename TO::template result; 35 | }; 36 | template 37 | using result = typename helper::type; 38 | }; 39 | }; 40 | 41 | template 42 | using apply_pack_to = typename F::template to::template result; 43 | template 44 | using apply_pack = typename F::template to::template result; 45 | 46 | template 47 | using apply_list_to = apply_pack_to, C, Ts...>; 48 | template 49 | using apply_list = apply_pack, Ts...>; 50 | 51 | 52 | } 53 | 54 | #endif //TYPICAL_APPLICATION_HPP 55 | -------------------------------------------------------------------------------- /include/typical/compose.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_COMPOSE_HPP 16 | #define TYPICAL_COMPOSE_HPP 17 | 18 | #include 19 | 20 | namespace typical 21 | { 22 | template 23 | struct compose; 24 | 25 | template <> 26 | struct compose<> 27 | { 28 | using continuation = identity; 29 | template 30 | struct to 31 | { 32 | using T = detail::to; 33 | template 34 | using result = typename T::template result; 35 | }; 36 | }; 37 | 38 | template 39 | struct compose 40 | { 41 | using continuation = typename F::continuation; 42 | template 43 | struct to 44 | { 45 | template 46 | using result = typename compose::template to>::template result; 47 | }; 48 | }; 49 | 50 | } 51 | #endif //TYPICAL_COMPOSE_HPP 52 | -------------------------------------------------------------------------------- /include/typical/conditional.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_CONDITIONAL_HPP 16 | #define TYPICAL_CONDITIONAL_HPP 17 | 18 | namespace typical 19 | { 20 | template 21 | struct conditional { 22 | template 23 | using result = T; 24 | }; 25 | 26 | template<> 27 | struct conditional { 28 | template 29 | using result = U; 30 | }; 31 | 32 | template 33 | using conditional_t = typename conditional::template result; 34 | 35 | } 36 | 37 | #endif //TYPICAL_CONDITIONAL_HPP 38 | -------------------------------------------------------------------------------- /include/typical/constant.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_CONSTANT_HPP 16 | #define TYPICAL_CONSTANT_HPP 17 | 18 | #include 19 | 20 | namespace typical 21 | { 22 | template 23 | struct typed_constant 24 | { 25 | using type = T; 26 | static constexpr T value{v}; 27 | constexpr operator type() const { return v;} 28 | }; 29 | 30 | template 31 | using constant = typed_constant, V>; 32 | 33 | template 34 | inline constexpr auto constant_v = constant{}; 35 | 36 | template 37 | constexpr constant<(v1+v2)> operator+(typed_constant,typed_constant) { return {};} 38 | template 39 | constexpr constant<(v1-v2)> operator-(typed_constant,typed_constant) { return {};} 40 | template 41 | constexpr constant<(v1/v2)> operator/(typed_constant,typed_constant) { return {};} 42 | template 43 | constexpr constant<(v1*v2)> operator*(typed_constant,typed_constant) { return {};} 44 | template 45 | constexpr constant<(v1%v2)> operator%(typed_constant,typed_constant) { return {};} 46 | template 47 | constexpr constant<(v1==v2)> operator==(typed_constant,typed_constant) { return {};} 48 | template 49 | constexpr constant<(v1!=v2)> operator!=(typed_constant,typed_constant) { return {};} 50 | template 51 | constexpr constant<(v1 operator<(typed_constant,typed_constant) { return {};} 52 | template 53 | constexpr constant<(v1<=v2)> operator<=(typed_constant,typed_constant) { return {};} 54 | template 55 | constexpr constant<(v1>v2)> operator>(typed_constant,typed_constant) { return {};} 56 | template 57 | constexpr constant<(v1>=v2)> operator>=(typed_constant,typed_constant) { return {};} 58 | template 59 | constexpr constant<(v1|v2)> operator|(typed_constant,typed_constant) { return {};} 60 | template 61 | constexpr constant<(v1&v2)> operator&(typed_constant,typed_constant) { return {};} 62 | template 63 | constexpr constant<(v1^v2)> operator^(typed_constant,typed_constant) { return {};} 64 | template 65 | constexpr constant<(v1&&v2)> operator&&(typed_constant,typed_constant) { return {};} 66 | template 67 | constexpr constant<(v1||v2)> operator||(typed_constant,typed_constant) { return {};} 68 | 69 | template 70 | constexpr constant operator!(typed_constant) { return {};} 71 | template 72 | constexpr constant<(~v1)> operator~(typed_constant) { return {};} 73 | 74 | } 75 | 76 | #endif //TYPICAL_CONSTANT_HPP 77 | -------------------------------------------------------------------------------- /include/typical/function_support.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * typical - C++ template meta programming library 3 | * 4 | * Copyright Björn Fahller 2018 5 | * 6 | * Use, modification and distribution is subject to the 7 | * Boost Software License, Version 1.0. (See accompanying 8 | * file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * Project home: https://github.com/rollbear/typical 12 | */ 13 | 14 | 15 | #ifndef TYPICAL_FUNCTION_SUPPORT_HPP 16 | #define TYPICAL_FUNCTION_SUPPORT_HPP 17 | 18 | #include 19 | 20 | #include 21 | 22 | namespace typical 23 | { 24 | 25 | namespace detail 26 | { 27 | 28 | template 29 | struct has_continuation 30 | { 31 | static constexpr bool value = false; 32 | }; 33 | 34 | template 35 | struct has_continuation> 36 | { 37 | static constexpr bool value = true; 38 | }; 39 | 40 | template ::value> 41 | struct to_ 42 | { 43 | using type = T; 44 | }; 45 | 46 | template 47 | struct to_ 48 | { 49 | using type = typename T::template to; 50 | }; 51 | 52 | 53 | template 54 | using to = typename to_::type; 55 | 56 | } 57 | 58 | template 59 | struct list {}; 60 | 61 | template class C> 62 | struct make { 63 | template 64 | using result = C; 65 | }; 66 | 67 | template 68 | using apply_one = typename F::template result; 69 | 70 | struct identity { 71 | template 72 | using result = T; 73 | }; 74 | 75 | template