├── TODO ├── .gitignore ├── .syntax ├── LICENSE ├── unconstexpr ├── unconstexpr.hpp ├── meta_partial.hpp ├── uniq_value.hpp ├── meta_any.hpp ├── meta_counter.hpp ├── tools │ ├── type_map.hpp │ ├── var_list.hpp │ ├── type_list.hpp │ └── type_string.hpp ├── meta_type.hpp ├── meta_tlist.hpp ├── meta_vlist.hpp └── meta_value.hpp ├── Makefile ├── tests ├── tools │ ├── println.hpp │ ├── auto_testing.hpp │ └── type_printer.hpp └── main.cpp └── README.md /TODO: -------------------------------------------------------------------------------- 1 | meta_tlist or meta_vlist: 2 | foreach, apply 3 | 4 | meta_vlist: 5 | add initialize method or a better transfer ( std::array ) 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | -------------------------------------------------------------------------------- /.syntax: -------------------------------------------------------------------------------- 1 | // calling conventions -*- C++ -*- 2 | 3 | namespace unconstexpr 4 | { 5 | namespace detail 6 | { 7 | struct PrivateToolType {}; 8 | struct public_tool_type {}; 9 | } 10 | 11 | template 12 | struct snake_case 13 | { 14 | struct ToolType {}; 15 | }; 16 | 17 | using type_case = ...; 18 | 19 | void method_or_function_name(type argumentName); 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Bastien Penavayre 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 | -------------------------------------------------------------------------------- /unconstexpr/unconstexpr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | #include "meta_counter.hpp" 25 | #include "meta_value.hpp" 26 | #include "meta_partial.hpp" 27 | #include "meta_type.hpp" 28 | #include "meta_tlist.hpp" 29 | #include "meta_vlist.hpp" 30 | #include "meta_any.hpp" 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2017 Bastien Penavayre 2 | 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | 10 | # The above copyright notice and this permission notice shall be included in 11 | # all copies or substantial portions of the Software. 12 | 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | # THE SOFTWARE. 20 | 21 | CXX = g++-7 22 | 23 | RM = rm -f 24 | 25 | NAME = test 26 | 27 | SRC = tests/main.cpp \ 28 | 29 | OBJ = $(SRC:.cpp=.o) 30 | 31 | COMMON = -W -Wall -Wextra -std=c++17 32 | 33 | CXXFLAGS = $(COMMON) -Iunconstexpr/ 34 | 35 | LINKING = $(COMMON) 36 | 37 | all: $(NAME) 38 | 39 | $(NAME): $(OBJ) 40 | $(CXX) $(OBJ) -o $(NAME) $(LINKING) 41 | clean: 42 | $(RM) $(OBJ) 43 | 44 | fclean: clean 45 | $(RM) $(NAME) 46 | 47 | re: fclean all 48 | -------------------------------------------------------------------------------- /tests/tools/println.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "type_printer.hpp" 26 | 27 | namespace log 28 | { 29 | template 30 | struct Joiner 31 | { 32 | template 33 | Joiner operator<<(T const &arg) 34 | { 35 | if constexpr (started) std::cout << ' '; 36 | std::cout << arg; 37 | return {}; 38 | } 39 | 40 | Joiner operator<<(std::ostream &(*f)(std::ostream &)) 41 | { 42 | std::cout << f; 43 | return {}; 44 | } 45 | }; 46 | 47 | template 48 | void Println(Args&&... args) 49 | { 50 | (log::Joiner<>() << ... << args) << std::endl; 51 | } 52 | } 53 | 54 | #define println(args...) log::Println(args, "<=", #args) 55 | #define printType(x) log::Println(make_type_printer(), "<=", #x) 56 | -------------------------------------------------------------------------------- /unconstexpr/meta_partial.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include 23 | #include "meta_counter.hpp" 24 | 25 | namespace unconstexpr 26 | { 27 | template struct partial; 28 | 29 | namespace detail 30 | { 31 | template 32 | struct partial_class : partial... {}; 33 | 34 | template)> 35 | constexpr size_t safe_next(int) { return T::next(); } 36 | 37 | template 38 | constexpr size_t safe_next(float) 39 | { 40 | if constexpr(R == 0) return T::next(); 41 | else return R; 42 | } 43 | 44 | template 45 | auto partial_tool_impl(std::index_sequence) { return partial_class{}; } 46 | } 47 | 48 | template(0)> 49 | struct partial; 50 | 51 | template 52 | using partial_t = decltype(detail::partial_tool_impl(std::make_index_sequence{})); 53 | 54 | template > 55 | struct partial_it : meta_counter {}; 56 | } 57 | -------------------------------------------------------------------------------- /unconstexpr/uniq_value.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | namespace unconstexpr 25 | { 26 | class uniq_value 27 | { 28 | struct Detail 29 | { 30 | template 31 | struct Flag 32 | { 33 | friend constexpr bool adl_flag(Flag); 34 | }; 35 | 36 | template 37 | struct Writer 38 | { 39 | friend constexpr bool adl_flag(Flag) 40 | { 41 | return true; 42 | } 43 | 44 | static constexpr unsigned value = N; 45 | }; 46 | 47 | template {})> 48 | static constexpr unsigned reader(int, unsigned r = reader(0)) 49 | { 50 | return r; 51 | } 52 | 53 | template 54 | static constexpr unsigned reader(float) 55 | { 56 | return Writer::value; 57 | } 58 | }; 59 | 60 | public: 61 | template 62 | static constexpr unsigned value = N; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /unconstexpr/meta_any.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "meta_type.hpp" 26 | 27 | namespace unconstexpr 28 | { 29 | template > 30 | class meta_any 31 | { 32 | using type = meta_type; 33 | 34 | public: 35 | template > 36 | static inline T value; 37 | 38 | template ()> 39 | static constexpr T change() 40 | { 41 | return value; 42 | } 43 | 44 | template ()> 45 | static constexpr T change(T const &newValue) 46 | { 47 | return (value = newValue); 48 | } 49 | 50 | template 51 | constexpr auto &operator*() const { 52 | return value<>; 53 | } 54 | 55 | template ()> 56 | constexpr auto &operator=(T const &newValue) const { 57 | return (value = newValue); 58 | } 59 | 60 | template 61 | friend T &operator<<(T &stream, meta_any const &) { 62 | return stream << meta_any::value<>; 63 | } 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /unconstexpr/meta_counter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * Filip Roséen 4 | * http://b.atch.se/posts/constexpr-meta-container 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "uniq_value.hpp" 28 | 29 | namespace unconstexpr 30 | { 31 | namespace detail 32 | { 33 | template 34 | class meta_counter 35 | { 36 | template 37 | struct Flag 38 | { 39 | friend constexpr bool adl_flag (Flag); 40 | }; 41 | 42 | template 43 | struct Writer 44 | { 45 | friend constexpr bool adl_flag (Flag) { return true; } 46 | static constexpr Type value = N; 47 | }; 48 | 49 | template{})> 50 | static constexpr Type reader (int, Flag, Type r = reader(0, Flag{})) 51 | { 52 | return r; 53 | } 54 | 55 | template 56 | static constexpr Type reader(float, Flag) 57 | { 58 | return N; 59 | } 60 | 61 | public: 62 | static constexpr Type value(Type r = reader(0, Flag{})) 63 | { 64 | return r; 65 | } 66 | 67 | template 68 | static constexpr Type next(Type r = Writer::value) 69 | { 70 | return r + Step; 71 | } 72 | }; 73 | 74 | template struct unique_type {}; 75 | } 76 | 77 | template > 78 | using meta_counter = detail::meta_counter, Type, Start, It>; 79 | } 80 | -------------------------------------------------------------------------------- /unconstexpr/tools/type_map.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace unconstexpr 27 | { 28 | namespace detail 29 | { 30 | template struct map; 31 | 32 | template 33 | struct map_item 34 | { 35 | using key = Key; 36 | using value = Value; 37 | }; 38 | 39 | template 40 | using map_replace_tool = std::conditional_t, 41 | map_item, 42 | T >; 43 | 44 | struct no_such_key {}; 45 | 46 | template 47 | constexpr auto map_get_tool() 48 | { 49 | if constexpr (std::is_same_v) return typename T::value{}; 50 | else if constexpr (sizeof...(Args) == 0) return no_such_key{}; 51 | else return map_get_tool(); 52 | }; 53 | 54 | template 55 | struct map 56 | { 57 | template 58 | static constexpr bool has_key = (std::is_same_v || ...); 59 | 60 | template 61 | using set = std::conditional_t, 62 | map...>, 63 | map > >; 64 | 65 | template 66 | using get = std::conditional_t, 67 | decltype(map_get_tool()), 68 | no_such_key>; 69 | 70 | using clear = map<>; 71 | }; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /unconstexpr/meta_type.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "meta_counter.hpp" 26 | 27 | namespace unconstexpr 28 | { 29 | namespace detail 30 | { 31 | template 32 | struct ReturnTool 33 | { 34 | using type = T; 35 | }; 36 | } 37 | 38 | template > 39 | class meta_type 40 | { 41 | using counter = detail::meta_counter; 42 | 43 | template 44 | struct Flag 45 | { 46 | friend constexpr auto adl_flag(Flag); 47 | }; 48 | 49 | template 50 | struct Writer 51 | { 52 | friend constexpr auto adl_flag(Flag) 53 | { 54 | return detail::ReturnTool{}; 55 | } 56 | 57 | using type = NewType; 58 | }; 59 | 60 | template 61 | struct Changer 62 | { 63 | template ::type> 65 | static constexpr int change() { return 0; } 66 | }; 67 | 68 | public: 69 | template ::type, 70 | int Index = counter::value()> 71 | using type = typename decltype(adl_flag(Flag{}))::type; 72 | 73 | template ::change()> 75 | static constexpr int change() 76 | { 77 | return 0; 78 | } 79 | 80 | template 81 | static constexpr int counter_value() 82 | { 83 | return Index; 84 | } 85 | 86 | private: 87 | template 88 | struct Changer, I> 89 | { 90 | static constexpr int change() { return 0; } 91 | }; 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /unconstexpr/tools/var_list.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | 28 | namespace unconstexpr::detail 29 | { 30 | template 31 | class var_list 32 | { 33 | template struct Select; 34 | template struct MergeTool; 35 | 36 | template 37 | struct Select> 38 | { 39 | using type = 40 | var_list(std::tuple(Args...))...>; 41 | }; 42 | 43 | template 44 | struct MergeTool> 45 | { 46 | using type = var_list; 47 | }; 48 | 49 | static constexpr size_t safe_sub(size_t value, size_t n) { 50 | return (value < n ? 0 : value - n); 51 | } 52 | 53 | template 54 | static constexpr auto tool_remove(std::index_sequence) 55 | { 56 | constexpr auto change = [](size_t value) { 57 | return value + (value >= toRemove ? 1 : 0); 58 | }; 59 | 60 | return std::index_sequence{}; 61 | } 62 | 63 | public: 64 | template 65 | using select = typename Select>::type; 66 | 67 | template 68 | using push_front = var_list; 69 | 70 | template 71 | using push_back = var_list; 72 | 73 | template 74 | using pop_front = select; 75 | 76 | template 77 | using pop_back = select<0, safe_sub(sizeof...(Args), N)>; 78 | 79 | template 80 | static constexpr auto item = std::get(std::tuple(Args...)); 81 | 82 | template class Holder> 83 | using transfer = Holder; 84 | 85 | template 86 | using merge = typename MergeTool::type; 87 | 88 | template 89 | using remove = typename 90 | Select<0, decltype(tool_remove(std::make_index_sequence{}))>::type; 91 | }; 92 | } 93 | -------------------------------------------------------------------------------- /unconstexpr/tools/type_list.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include 26 | 27 | namespace unconstexpr::detail 28 | { 29 | template 30 | class type_list 31 | { 32 | template struct Select; 33 | template struct MergeTool; 34 | 35 | template 36 | struct Select> 37 | { 38 | using type = 39 | type_list>...>; 40 | }; 41 | 42 | template 43 | struct MergeTool> 44 | { 45 | using type = type_list; 46 | }; 47 | 48 | static constexpr size_t safe_sub(size_t value, size_t n) { 49 | return (value < n ? 0 : value - n); 50 | } 51 | 52 | template 53 | static constexpr auto tool_remove(std::index_sequence) 54 | { 55 | constexpr auto change = [](size_t value) { 56 | return value + (value >= toRemove ? 1 : 0); 57 | }; 58 | 59 | return std::index_sequence{}; 60 | } 61 | 62 | public: 63 | template > 64 | using select = typename Select::type; 65 | 66 | template 67 | using push_front = type_list; 68 | 69 | template 70 | using push_back = type_list; 71 | 72 | template 73 | using pop_front = select; 74 | 75 | template 76 | using pop_back = select<0, safe_sub(sizeof...(Args), N)>; 77 | 78 | template 79 | using item = std::tuple_element_t>; 80 | 81 | template class Holder> 82 | using transfer = Holder; 83 | 84 | template 85 | using merge = typename MergeTool::type; 86 | 87 | template 88 | using remove = typename 89 | Select<0,decltype(tool_remove(std::make_index_sequence{}))>::type; 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /unconstexpr/meta_tlist.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "meta_type.hpp" 26 | #include "tools/type_list.hpp" 27 | 28 | namespace unconstexpr 29 | { 30 | template > 31 | class meta_tlist 32 | { 33 | using parent = meta_type, meta_tlist, 0>; 34 | 35 | public: 36 | template > 37 | using current_type = current; 38 | 39 | template 40 | static constexpr int push_front(int = parent::template change::template 41 | push_front>()) { return 0; } 42 | 43 | template 44 | static constexpr int push_back(int = parent::template change::template 45 | push_back>()) { return 0; } 46 | 47 | template 48 | static constexpr int pop_front(int = parent::template change::template 49 | pop_front>()) { return 0; } 50 | 51 | template 52 | static constexpr int pop_back(int = parent::template change::template 53 | pop_back>()) { return 0; } 54 | 55 | template ::template item > 56 | using item = Ret; 57 | 58 | template class Holder, 59 | class Ret = typename current_type<>::template transfer > 60 | using transfer = Ret; 61 | 62 | template 63 | static constexpr int insert_list(int = parent::template change::template 64 | merge>()) { return 0; } 65 | 66 | static constexpr int clear(int = parent::template change>()) { return 0; } 67 | 68 | template 69 | static constexpr int select(int = parent::template change::template 70 | select>()) { return 0; } 71 | 72 | template 73 | static constexpr int remove(int = parent::template change::template 74 | remove>()) { return 0; } 75 | 76 | template 77 | static constexpr int counter_value() 78 | { 79 | return Index; 80 | } 81 | }; 82 | } 83 | -------------------------------------------------------------------------------- /tests/tools/auto_testing.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | #include "println.hpp" 25 | 26 | #ifndef DONT_USE_META 27 | 28 | # include "meta_tlist.hpp" 29 | template void unit(T); 30 | 31 | namespace auto_testing 32 | { 33 | using unit_list = unconstexpr::meta_tlist<>; 34 | 35 | template 36 | struct TestLogger final 37 | { 38 | template ()> 39 | using pusher = TestLogger; 40 | 41 | static void run() { unit(TestLogger{}); } 42 | static constexpr Char repr[] = {chars..., ':', '\0'}; 43 | 44 | TestLogger() { log::Println("TESTING", repr); } 45 | ~TestLogger() { log::Println(); } 46 | }; 47 | 48 | template 49 | constexpr void run(detail::type_list) 50 | { 51 | (Args::run(), ...); 52 | } 53 | }; 54 | 55 | template 56 | constexpr auto operator""_logger_string() { 57 | return (typename auto_testing::TestLogger::template pusher<>){}; 58 | } 59 | 60 | # define new_unit(x) template <> void unit(decltype(x ## _logger_string)) 61 | # define run_units_so_far() auto_testing::run(auto_testing::unit_list::current_type<>{}) 62 | 63 | #else /*DONT_USE_META*/ 64 | 65 | namespace auto_testing 66 | { 67 | template 68 | struct TestLogger final 69 | { 70 | static constexpr Char repr[] = {Chars..., ':', '\0'}; 71 | }; 72 | 73 | template 74 | struct Number final 75 | { 76 | Number(std::integral_constant) 77 | { 78 | if constexpr(N != 0) log::Println(); 79 | log::Println("TESTING", Literal::repr); 80 | } 81 | }; 82 | 83 | template 84 | constexpr auto make_integral(std::index_sequence) -> 85 | std::tuple...> 86 | { 87 | return {}; 88 | } 89 | } 90 | 91 | template 92 | constexpr auto operator""_logger_string() -> auto_testing::TestLogger { 93 | return {}; 94 | } 95 | 96 | template 97 | void unit(std::integral_constant) {} 98 | 99 | # define new_unit(x) \ 100 | void unit(auto_testing::Number<__COUNTER__, decltype(x ## _logger_string)>) 101 | 102 | # define run_units_so_far() \ 103 | std::apply([](auto... args) { (unit(args), ...); }, \ 104 | auto_testing::make_integral(std::make_index_sequence<__COUNTER__>{})); 105 | 106 | #endif /*DONT_USE_META*/ 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unconstexpr 2 | 3 | #### An ODR violation story 4 | a c++17 header library that implements variant constexpr functions and types. 5 | 6 | ### Test it online now with Coliru online g++ compiler 7 | 8 | 9 | 10 | 11 | __Disclaimer:__ 12 | * This project only targets __g++7__ and is only for fun. 13 | * It is inspired by Filip Roséen's blog http://b.atch.se/. 14 | * His blog is great go check it out for a c++ standart compilant implementation of some of the features of this library. 15 | 16 | ### template instanciation uniqueness 17 | All meta_X templated types provided by this library have unique template instanciation. 18 | ```c++ 19 | static_assert(!std::is_same_v, meta_X<>>, "Will not fire"); 20 | ``` 21 | 22 | ### compile time counter 23 | ```c++ 24 | #include "unconstexpr/meta_counter.hpp" 25 | using namespace unconstexpr; 26 | 27 | int main() 28 | { 29 | using counter = meta_counter<>; 30 | constexpr int i = counter::value(); // 0 31 | counter::next(); // 1 32 | static_assert(i != counter::value(), "Will not fire"); 33 | } 34 | ``` 35 | ### compile time type-safe any (value not constexpr) 36 | ```c++ 37 | #include "unconstexpr/meta_any.hpp" 38 | using namespace unconstexpr; 39 | 40 | int main() 41 | { 42 | meta_any var; 43 | var = 35; 44 | println(*var); //35 45 | var = 3.14; 46 | type_printer(); //double& 47 | println(*var); //3.14 48 | var = "word"s; 49 | type_printer(); //std::string& 50 | println(*var); //word 51 | std::cout << var << std::endl; //provides an operator<< 52 | } 53 | ``` 54 | ### constexpr typesafe any : meta_value 55 | ```c++ 56 | #include "unconstexpr/meta_value.hpp" 57 | using namespace unconstexpr; 58 | 59 | //carg(x) is a macro and is required for every assignation operation 60 | int main() 61 | { 62 | using type = unconstexpr::meta_value<>; 63 | static_assert(type::value<> == false); 64 | static_assert(std::is_same_v, std::false_type>); 65 | 66 | constexpr type tmp = carg(42); 67 | static_assert(*tmp == 42); 68 | tmp += carg(3); 69 | static_assert(*tmp == 45); 70 | tmp -= carg(42); 71 | static_assert(*tmp == 3); 72 | tmp *= carg(3); 73 | static_assert(*tmp == 9); 74 | 75 | static_assert(tmp.compiles()); 76 | tmp /= carg(0); 77 | if constexpr(!tmp.compiles()) 78 | tmp.undo(); 79 | static_assert(*tmp == 9); 80 | 81 | tmp = carg([]() { return 42; }); 82 | static_assert(tmp() == 42); 83 | 84 | tmp = carg(std::array{42, 314}); 85 | static_assert(tmp[1] == 314); 86 | } 87 | ``` 88 | 89 | ### partial class definition 90 | ```c++ 91 | #include "unconstexpr/meta_partial.hpp" 92 | using namespace unconstexpr; 93 | 94 | using A = partial_it<>; 95 | 96 | template<> 97 | struct unconstexpr::partial 98 | { 99 | int i; 100 | }; 101 | 102 | template<> 103 | struct unconstexpr::partial 104 | { 105 | int j; 106 | }; 107 | 108 | int main() 109 | { 110 | partial_t tmp; 111 | (void)tmp.i; 112 | (void)tmp.j; 113 | } 114 | 115 | template<> 116 | struct unconstexpr::partial 117 | { 118 | int k; 119 | }; 120 | 121 | void func() 122 | { 123 | partial_t tmp; 124 | (void)tmp.i; 125 | (void)tmp.j; 126 | (void)tmp.k; 127 | } 128 | ``` 129 | 130 | ## compile time variant type list 131 | ```c++ 132 | #include "unconstexpr/meta_tlist.hpp" 133 | using namespace unconstexpr; 134 | 135 | int main() 136 | { 137 | using list = meta_tlist<>; 138 | 139 | type_printer>(); //type_list<> 140 | list::push_front(); 141 | list::push_front(); 142 | type_printer>(); //type_list 143 | list::remove<0>(); 144 | type_printer>(); //double 145 | } 146 | ``` 147 | 148 | ## compile time value type list 149 | ```c++ 150 | #include "unconstexpr/meta_vlist.hpp" 151 | using namespace unconstexpr; 152 | 153 | int main() 154 | { 155 | using list = meta_vlist<>; 156 | 157 | type_printer>(); //var_list<> 158 | list::push_front<42>(); 159 | list::push_front(); 160 | type_printer>(); //var_list<42, nullptr> 161 | list::remove<0>(); 162 | static_assert(list::item<0> == nullptr); 163 | } 164 | ``` 165 | -------------------------------------------------------------------------------- /tests/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #include "unconstexpr.hpp" 23 | using namespace unconstexpr; 24 | #include "tools/auto_testing.hpp" 25 | 26 | void unit_launcher(); 27 | 28 | int main () 29 | { 30 | static_assert(!std::is_same_v, meta_counter<>>); 31 | static_assert(!std::is_same_v, meta_type>); 32 | static_assert(!std::is_same_v, meta_tlist<>>); 33 | static_assert(!std::is_same_v, meta_vlist<>>); 34 | static_assert(!std::is_same_v, meta_any>); 35 | static_assert(!std::is_same_v, meta_value<>>); 36 | 37 | unit_launcher(); 38 | } 39 | 40 | new_unit("meta_counter") 41 | { 42 | using counter = meta_counter<>; 43 | 44 | println(counter::value()); 45 | println(counter::next()); 46 | println(counter::next()); 47 | println(counter::next()); 48 | } 49 | 50 | new_unit("meta_tlist") 51 | { 52 | using list = meta_tlist<>; 53 | 54 | printType(list::current_type<>); 55 | list::push_front(); 56 | list::push_front(); 57 | printType(list::current_type<>); 58 | list::remove<-1>(); 59 | printType(list::item<0>); 60 | } 61 | 62 | static constexpr int i = 0, j = 25; 63 | 64 | new_unit("meta_vlist") 65 | { 66 | using list = meta_vlist<>; 67 | 68 | printType(list::current_type<>); 69 | list::push_back<&i, 52>(); 70 | printType(list::current_type<>); 71 | list::push_back<&i, 52>(); 72 | printType(list::current_type<>); 73 | println(list::item<0>, list::item<1>); 74 | constexpr auto v = list::value_transfer(); 75 | printType(decltype(v)); 76 | list::clear(); 77 | printType(decltype(list::value_transfer())); 78 | list::push_front<42>(); 79 | println(list::item<0>); 80 | // list::foreach; 81 | // std::apply; 82 | } 83 | 84 | new_unit("meta_any") 85 | { 86 | meta_any v; 87 | 88 | v = 5; 89 | println(*v, make_type_printer()); 90 | static_assert(std::is_same_v); 91 | v = 3.14; 92 | println(*v, make_type_printer()); 93 | static_assert(std::is_same_v); 94 | v = "Hello"s; 95 | println(*v, make_type_printer()); 96 | static_assert(std::is_same_v); 97 | std::cout << "\"operator<<\" test: " << v << std::endl; 98 | } 99 | 100 | new_unit("meta_value") 101 | { 102 | using type = unconstexpr::meta_value<>; 103 | static_assert(type::value<> == false); 104 | static_assert(std::is_same_v, std::false_type>); 105 | 106 | constexpr type tmp = carg(42); 107 | static_assert(*tmp == 42); 108 | tmp += carg(3); 109 | static_assert(*tmp == 45); 110 | tmp -= carg(42); 111 | static_assert(*tmp == 3); 112 | tmp *= carg(3); 113 | static_assert(*tmp == 9); 114 | 115 | static_assert(tmp.compiles()); 116 | tmp /= carg(0); 117 | if constexpr(!tmp.compiles()) tmp.undo(); 118 | static_assert(*tmp == 9); 119 | 120 | tmp = carg([]() { return 42; }); 121 | static_assert(tmp() == 42); 122 | 123 | tmp = carg(std::array{42, 314}); 124 | static_assert(tmp[1] == 314); 125 | } 126 | 127 | void unit_launcher() 128 | { 129 | run_units_so_far(); 130 | } 131 | -------------------------------------------------------------------------------- /unconstexpr/tools/type_string.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace unconstexpr::detail 30 | { 31 | template 32 | struct type_string 33 | { 34 | constexpr type_string() {} 35 | static constexpr Char c_str[sizeof...(chars) + 1] = {chars..., '\0'}; 36 | static constexpr std::string_view string = c_str; 37 | static constexpr size_t length = sizeof...(chars); 38 | 39 | template 40 | constexpr auto substr() 41 | { 42 | constexpr size_t 43 | diff = std::abs(to - from), 44 | min = std::min(from, to); 45 | constexpr int sign = (min == from : 1 : -1); 46 | 47 | return [](std::index_sequence) 48 | { 49 | type_string{}; 50 | }(std::make_index_sequence{}); 51 | } 52 | 53 | template 54 | constexpr bool starts_with(type_string const &) 55 | { 56 | constexpr size_t osize = sizeof...(chars_2); 57 | if constexpr (osize > size) return false; 58 | else if constexpr (osize == size) return ((chars == (Char)chars_2) && ...); 59 | else 60 | { 61 | return [](std::index_sequence) 62 | { 63 | return ((c_str[Is] == (Char)chars_2) && ...); 64 | }(std::make_index_sequence{}); 65 | } 66 | } 67 | 68 | template 69 | constexpr size_t find(type_string const &) 70 | { 71 | using otype = type_string; 72 | for (size_t i = 0; i < size && i < otype::size; i++) 73 | if (c_str[i] == otype::c_str[0]) 74 | { 75 | size_t from = i, size_t j = 0; 76 | for(; i < size && j < otype::size 77 | && c_str[i] == otype::c_str[j]; (i++, j++)); 78 | if (j >= otype::size && i <= size) 79 | return from; 80 | i--; 81 | } 82 | return -1; 83 | } 84 | }; 85 | } 86 | 87 | template 88 | constexpr bool operator==(unconstexpr::detail::type_string const&, 89 | unconstexpr::detail::type_string const&) 90 | { 91 | return (sizeof...(chars_1) && sizeof...(chars_2)) && 92 | ((chars_1 == ((C_1)chars_2)) && ...); 93 | } 94 | 95 | template 96 | constexpr auto operator+(unconstexpr::detail::type_string const&, 97 | unconstexpr::detail::type_string const&) 98 | { 99 | return unconstexpr::detail::type_string{}; 100 | } 101 | 102 | template 103 | constexpr auto operator""_tstr() 104 | { 105 | return unconstexpr::detail::type_string{}; 106 | } 107 | -------------------------------------------------------------------------------- /unconstexpr/meta_vlist.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | #pragma once 24 | 25 | #include "meta_type.hpp" 26 | #include "tools/var_list.hpp" 27 | 28 | namespace unconstexpr 29 | { 30 | namespace detail 31 | { 32 | template 33 | struct ValueHolder 34 | { 35 | constexpr ValueHolder(int) {} 36 | 37 | template class NewHolder> 38 | static constexpr NewHolder transfer() 39 | { 40 | return {Args...}; 41 | } 42 | }; 43 | } 44 | 45 | template > 46 | class meta_vlist 47 | { 48 | using parent = meta_type, meta_vlist, 0>; 49 | 50 | public: 51 | template > 52 | using current_type = Current; 53 | 54 | template 55 | static constexpr int push_front(int = parent::template change::template 56 | push_front>()) { return 0; } 57 | 58 | template 59 | static constexpr int push_back(int = parent::template change::template 60 | push_back>()) { return 0; } 61 | 62 | template 63 | static constexpr int pop_front(int = parent::template change::template 64 | pop_front>()) { return 0; } 65 | 66 | template 67 | static constexpr int pop_back(int = parent::template change::template 68 | pop_back>()) { return 0; } 69 | 70 | template ::template item > 71 | static constexpr auto item = Ret; 72 | 73 | template class Holder, 74 | class Ret = typename current_type<>::template transfer > 75 | using transfer = Ret; 76 | 77 | template class Holder, int = parent::counter_value()> 78 | static constexpr auto value_transfer() 79 | { 80 | return current_type<>::template transfer:: 81 | template transfer(); 82 | } 83 | 84 | template 85 | static constexpr int insert_list(int = parent::template change::template 86 | merge>()) { return 0; } 87 | 88 | static constexpr int clear(int = parent::template change>()) { return 0; } 89 | 90 | template 91 | static constexpr int select(int = parent::template change::template 92 | select>()) { return 0; } 93 | 94 | template 95 | static constexpr int remove(int = parent::template change::template 96 | remove>()) { return 0; } 97 | 98 | template 99 | static constexpr int counter_value() 100 | { 101 | return Index; 102 | } 103 | }; 104 | } 105 | -------------------------------------------------------------------------------- /tests/tools/type_printer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | using namespace std::literals; 31 | 32 | namespace type_repr 33 | { 34 | class NoPrint {}; 35 | 36 | inline std::string find_class_name(std::string const &name) 37 | { 38 | std::size_t b = name.size(); 39 | std::size_t open = 0; 40 | 41 | for (std::size_t i = 0; i < name.size(); i++) 42 | if (name[i] == '>') 43 | --open; 44 | else if (name[i] == '<') 45 | if (open++ == 0) 46 | b = i; 47 | return name.substr(0, b); 48 | } 49 | 50 | inline bool char_to_string(char c, std::string &res) 51 | { 52 | if ((c >= 1 && c <= 6) || (c >= 14 && c <= 31) || c == 127) 53 | return false; 54 | if (c >= ' ') 55 | res = "'"s + c + "'"; 56 | else 57 | res = "'\\"s + std::map({ 58 | {'\0', '0'}, {'\a', 'a'}, {'\b', 'b'}, {'\t', 't'}, 59 | {'\n', 'n'}, {'\v', 'v'}, {'\f', 'f'}, {'\r', 'r'} 60 | })[c] + '\''; 61 | return true; 62 | } 63 | 64 | inline void charcast_replace(std::string &str) 65 | { 66 | size_t index = 0; 67 | const std::string motif = "(char)"; 68 | while ((index = str.find(motif, index)) != std::string::npos) 69 | { 70 | size_t end = 0; 71 | std::string with; 72 | if (char_to_string((char)std::stoi(&str[index + motif.size()], &end), with)) { 73 | str.replace(index, motif.size() + end, with); 74 | index -= ((motif.size() + end) - with.size()); 75 | } 76 | } 77 | } 78 | 79 | template 80 | struct TypePrinter {}; 81 | 82 | template 83 | std::ostream& operator<<(std::ostream &stream, TypePrinter) 84 | { 85 | if constexpr (!std::is_same_v) 86 | { 87 | int status = -4; 88 | const char *name = typeid(T).name(); 89 | std::string true_name = abi::__cxa_demangle(name, 0, 0, &status); 90 | std::string class_name = find_class_name(true_name); 91 | std::string namespe = [&]() -> std::string { 92 | std::size_t i = class_name.rfind("::"); 93 | if (i != std::string::npos) 94 | return class_name.substr(0, i); 95 | else 96 | return ""; 97 | }(); 98 | if (!namespe.empty()) { 99 | std::string::size_type n = 0; 100 | while ( ( n = true_name.find( namespe, n ) ) != std::string::npos ) 101 | { 102 | true_name.replace( n, namespe.size(), "" ); 103 | n += 0; 104 | } 105 | } 106 | charcast_replace(true_name); 107 | stream << true_name; 108 | if (!namespe.empty()) 109 | stream << " (:: ==> " + namespe + ")"; 110 | } 111 | if constexpr (new_line) stream << std::endl; 112 | return stream; 113 | } 114 | 115 | template 116 | struct ValuePrinter {}; 117 | 118 | template 119 | std::ostream& operator<<(std::ostream &stream, ValuePrinter) 120 | { 121 | if constexpr (new_line) return stream << T << std::endl; 122 | else return stream << T; 123 | } 124 | 125 | template 126 | void type_printer() 127 | { 128 | std::cout << TypePrinter(); 129 | } 130 | 131 | template 132 | void type_printer() 133 | { 134 | std::cout << ValuePrinter(); 135 | } 136 | 137 | template 138 | void make_type_printer(T const &) { 139 | type_printer(); 140 | } 141 | 142 | template 143 | auto make_type_printer() 144 | { 145 | return TypePrinter(); 146 | } 147 | 148 | template 149 | auto make_type_printer() 150 | { 151 | return ValuePrinter(); 152 | } 153 | } 154 | 155 | using type_repr::type_printer; 156 | using type_repr::make_type_printer; 157 | -------------------------------------------------------------------------------- /unconstexpr/meta_value.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Bastien Penavayre 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | #include "meta_type.hpp" 28 | 29 | namespace unconstexpr 30 | { 31 | namespace detail 32 | { 33 | static constexpr auto false_type_lambda = []() { return std::false_type{}; }; 34 | 35 | template 36 | constexpr decltype(auto) lambda_op = []() 37 | { 38 | decltype(auto) l = ((Prev*)nullptr)->operator()(); 39 | decltype(auto) r = ((Next*)nullptr)->operator()(); 40 | if constexpr (type == '+') return l + r; 41 | else if constexpr(type == '-') return l - r; 42 | else if constexpr (type == '*') return l * r; 43 | else if constexpr (type == '/') return l / r; 44 | else return l; 45 | }; 46 | } 47 | 48 | template > 49 | struct meta_value 50 | { 51 | static constexpr meta_value instance = {}; 52 | 53 | /*back-end:*/ 54 | using lambda_type = meta_type; 55 | 56 | template> 57 | static constexpr auto value = ((R*)nullptr)->operator()(); 58 | 59 | template> 60 | using type = std::decay_t)>; 61 | 62 | /*Tool for undo() & undo_g() */ 63 | template 64 | static constexpr int index_safe_sub(int I) { return std::max(0, C - I); } 65 | 66 | /*Tool for is_valid & compiles()*/ 67 | template, 68 | bool = (((R*)nullptr)->operator()(), true)> 69 | static constexpr bool ok_tool(int) { return true; } 70 | static constexpr bool ok_tool(float) { return false; } 71 | 72 | /*front-end:*/ 73 | constexpr meta_value() = default; 74 | 75 | template()> 76 | constexpr meta_value(const T &) {} 77 | 78 | template()> 79 | constexpr const auto &operator=(const T &) const { return *this; } 80 | 81 | template, 83 | int = lambda_type::template change()> 84 | static constexpr int undo_g() { return 0; } 85 | 86 | template()> 87 | constexpr int undo() const { return 0; } 88 | 89 | template 90 | static constexpr bool compiles_g() { return R; } 91 | 92 | template 93 | constexpr bool compiles() const { return R; } 94 | 95 | template > 97 | constexpr auto &operator*() const { return value; } 98 | 99 | /*normal operators*/ 100 | template > 103 | constexpr operator T() const { return static_cast(value); } 104 | 105 | template > 106 | constexpr decltype(auto) operator+(T&& arg) const { return value + arg; } 107 | 108 | template > 109 | constexpr decltype(auto) operator-(T&& arg) const { return value - arg; } 110 | 111 | template > 112 | constexpr decltype(auto) operator*(T&& arg) const { return value * arg; } 113 | 114 | template > 115 | constexpr decltype(auto) operator/(T&& arg) const { return value / arg; } 116 | 117 | template > 118 | constexpr decltype(auto) operator[](T&& arg) const { return value[std::forward(arg)]; } 119 | 120 | template > 121 | constexpr decltype(auto) operator()(Args&&... args) const { return value(std::forward(args)...); } 122 | 123 | /*assigment operators*/ 124 | template, 125 | int = lambda_type::template change)>()> 126 | constexpr auto &operator+=(T const &) const { return *this; } 127 | 128 | template, 129 | int = lambda_type::template change)>()> 130 | constexpr auto &operator-=(T const &) const { return *this; } 131 | 132 | template, 133 | int = lambda_type::template change)>()> 134 | constexpr auto &operator*=(T const &) const { return *this; } 135 | 136 | template, 137 | int = lambda_type::template change)>()> 138 | constexpr auto &operator/=(T const &) const { return *this; } 139 | }; 140 | } 141 | 142 | #define carg(...) ([]{return __VA_ARGS__; }) 143 | --------------------------------------------------------------------------------