├── C++_TMP ├── CMakeLists.txt ├── variadics.h ├── policies.h ├── sequences.h ├── common.h ├── traits.h ├── member_detection.h ├── compile_time_computation.h ├── main.cpp ├── solutions.h └── tuple_cat.h ├── .gitignore ├── LICENSE └── README.md /C++_TMP/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.3) 2 | project(TMP) 3 | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") 5 | 6 | set(SOURCE_FILES main.cpp variadics.h compile_time_computation.h common.h traits.h member_detection.h sequences.h policies.h tuple_cat.h solutions.h) 7 | add_executable(TMP ${SOURCE_FILES}) -------------------------------------------------------------------------------- /.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 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # CLion folders 31 | .idea/ 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Sasha Goldshtein 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 | 23 | -------------------------------------------------------------------------------- /C++_TMP/variadics.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 09/12/2015. 3 | // 4 | 5 | #ifndef TMP_VARIADICS_H 6 | #define TMP_VARIADICS_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace variadics { 14 | 15 | void print() {} 16 | 17 | template 18 | void print(T&& v, Ts&&... vs) { 19 | std::cout << v << '\n'; 20 | print(std::forward(vs)...); 21 | } 22 | 23 | void printf(std::string const& format) { 24 | for (auto c : format) { 25 | if (c == '%') 26 | throw std::logic_error("too many format specifiers provided"); 27 | 28 | std::cout << c; 29 | } 30 | } 31 | 32 | template 33 | void printf(std::string const& format, T&& t, Rest&&... rest) { 34 | for (auto i = 0ull; i < format.size(); ++i) { 35 | if (format[i] == '%') { 36 | std::cout << std::forward(t); 37 | printf(format.substr(i+1), std::forward(rest)...); 38 | return; 39 | } else { 40 | std::cout << format[i]; 41 | } 42 | } 43 | throw std::logic_error("too many parameters provided"); 44 | } 45 | 46 | } 47 | 48 | #endif //TMP_VARIADICS_H 49 | -------------------------------------------------------------------------------- /C++_TMP/policies.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 12/13/15. 3 | // 4 | 5 | #ifndef TMP_POLICIES_H 6 | #define TMP_POLICIES_H 7 | 8 | #include 9 | 10 | namespace policies { 11 | 12 | template 13 | class smart_ptr { 14 | T* ptr_; 15 | public: 16 | smart_ptr(T* ptr) : ptr_{ ptr } { 17 | SafetyPolicy::test(ptr); 18 | } 19 | 20 | T& operator*() { 21 | SafetyPolicy::test(ptr_); 22 | return *ptr_; 23 | } 24 | 25 | T const& operator*() const { 26 | SafetyPolicy::test(ptr_); 27 | return *ptr_; 28 | } 29 | 30 | void reset(T* ptr) { 31 | SafetyPolicy::test(ptr_); 32 | ptr_ = ptr; 33 | } 34 | 35 | ~smart_ptr() { 36 | delete ptr_; 37 | } 38 | }; 39 | 40 | struct unsafe_policy { 41 | static void test(void*) {} 42 | }; 43 | 44 | struct non_null_policy { 45 | static void test(void* ptr) { 46 | if (ptr == nullptr) { 47 | throw std::invalid_argument("pointer was null"); 48 | } 49 | } 50 | }; 51 | 52 | template 53 | using unsafe_ptr = smart_ptr; 54 | 55 | template 56 | using non_null_ptr = smart_ptr; 57 | 58 | } 59 | 60 | #endif //TMP_POLICIES_H 61 | -------------------------------------------------------------------------------- /C++_TMP/sequences.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 12/13/15. 3 | // 4 | 5 | #ifndef TMP_SEQUENCES_H 6 | #define TMP_SEQUENCES_H 7 | 8 | #include 9 | 10 | #include "variadics.h" 11 | 12 | namespace sequences { 13 | 14 | template 15 | struct int_seq { 16 | constexpr static size_t length = sizeof...(Ns); 17 | using type = int_seq; 18 | }; 19 | 20 | template 21 | struct push_front_seq; 22 | 23 | template 24 | struct push_front_seq> { 25 | using type = int_seq; 26 | }; 27 | 28 | template 29 | struct push_back_seq; 30 | 31 | template 32 | struct push_back_seq> { 33 | using type = int_seq; 34 | }; 35 | 36 | template 37 | struct make_seq { 38 | using type = typename push_back_seq::type>::type; 39 | }; 40 | 41 | template <> 42 | struct make_seq<0> { 43 | using type = int_seq<0>; 44 | }; 45 | 46 | template 47 | using make_index_seq = typename make_seq::type; 48 | 49 | template 50 | void print_tuple(Tup const& tup, int_seq) { 51 | variadics::print(std::get(tup)...); 52 | } 53 | 54 | template 55 | void print_tuple(Tup const& tup) { 56 | constexpr size_t size = std::tuple_size::value; 57 | print_tuple(tup, typename make_seq::type{}); 58 | } 59 | 60 | } 61 | 62 | #endif //TMP_SEQUENCES_H 63 | -------------------------------------------------------------------------------- /C++_TMP/common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 09/12/2015. 3 | // 4 | 5 | #ifndef TMP_COMMON_H 6 | #define TMP_COMMON_H 7 | 8 | template 9 | struct is { 10 | using type = T; 11 | }; 12 | 13 | template 14 | struct bool_t : is> { 15 | constexpr operator bool() const { return B; } 16 | constexpr static bool value = B; 17 | }; 18 | 19 | using true_t = bool_t; 20 | using false_t = bool_t; 21 | 22 | template 23 | struct same_t : false_t {}; 24 | 25 | template 26 | struct same_t : true_t {}; 27 | 28 | template 29 | constexpr bool same_v = typename same_t::type{}; 30 | 31 | template 32 | struct select_t; 33 | 34 | template 35 | struct select_t : is {}; 36 | 37 | template 38 | struct select_t : is {}; 39 | 40 | template 41 | struct integral_t : false_t {}; 42 | 43 | template <> struct integral_t : true_t {}; 44 | template <> struct integral_t : true_t {}; 45 | template <> struct integral_t : true_t {}; 46 | template <> struct integral_t : true_t {}; 47 | template <> struct integral_t : true_t {}; 48 | template <> struct integral_t : true_t {}; 49 | template <> struct integral_t : true_t {}; 50 | template <> struct integral_t : true_t {}; 51 | template <> struct integral_t : true_t {}; 52 | template <> struct integral_t : true_t {}; 53 | 54 | template 55 | struct allow_if_t {}; 56 | 57 | template 58 | struct allow_if_t : is {}; 59 | 60 | template 61 | T&& val_of_t(); 62 | 63 | #endif //TMP_COMMON_H 64 | -------------------------------------------------------------------------------- /C++_TMP/traits.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 12/11/15. 3 | // 4 | 5 | #ifndef TMP_TRAITS_H 6 | #define TMP_TRAITS_H 7 | 8 | #include 9 | #include 10 | 11 | namespace traits { 12 | 13 | namespace detail { 14 | // Source: http://en.cppreference.com/w/cpp/string/char_traits 15 | struct ci_char_traits : public std::char_traits { 16 | static bool eq(char c1, char c2) { 17 | return std::toupper(c1) == std::toupper(c2); 18 | } 19 | 20 | static bool lt(char c1, char c2) { 21 | return std::toupper(c1) < std::toupper(c2); 22 | } 23 | 24 | static int compare(char const* s1, char const* s2, size_t n) { 25 | while (n-- != 0) { 26 | if (std::toupper(*s1) < std::toupper(*s2)) return -1; 27 | if (std::toupper(*s1) > std::toupper(*s2)) return 1; 28 | ++s1; 29 | ++s2; 30 | } 31 | return 0; 32 | } 33 | 34 | static char const* find(char const* s, int n, char a) { 35 | auto const ua(std::toupper(a)); 36 | while (n-- != 0) { 37 | if (std::toupper(*s) == ua) 38 | return s; 39 | s++; 40 | } 41 | return nullptr; 42 | } 43 | }; 44 | 45 | template 46 | OutIt copy_helper(InIt first, InIt last, OutIt out, false_t) { 47 | std::cout << "using slow copy_helper for OutIt = " << typeid(OutIt).name() << '\n'; 48 | for (; first != last; ++first, ++out) { 49 | *out = *first; 50 | } 51 | return out; 52 | } 53 | 54 | template 55 | OutIt copy_helper(InIt first, InIt last, OutIt out, true_t) { 56 | std::cout << "using fast copy_helper for OutIt = " << typeid(OutIt).name() << '\n'; 57 | size_t count = (last - first); 58 | std::memmove(out, first, count * sizeof(*first)); 59 | return out + count; 60 | } 61 | 62 | template 63 | struct is_safe_to_memmove_iter { 64 | using decayed_in_t = std::decay_t())>; 65 | using decayed_out_t = std::decay_t())>; 66 | using type = typename bool_t< 67 | same_v && 68 | std::is_pointer::value && 69 | std::is_trivially_copy_assignable::value 70 | >::type; 71 | }; 72 | 73 | template 74 | using is_safe_to_memmove_iter_t = typename is_safe_to_memmove_iter::type; 75 | } 76 | 77 | typedef std::basic_string ci_string; 78 | 79 | template 80 | OutIt copy(InIt first, InIt last, OutIt out) { 81 | return detail::copy_helper(first, last, out, 82 | typename detail::is_safe_to_memmove_iter_t::type{}); 83 | } 84 | } 85 | 86 | #endif //TMP_TRAITS_H 87 | -------------------------------------------------------------------------------- /C++_TMP/member_detection.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Sasha Goldshtein on 12/13/15. 3 | // 4 | 5 | #ifndef TMP_MEMBER_DETECTION_H 6 | #define TMP_MEMBER_DETECTION_H 7 | 8 | #include 9 | #include 10 | 11 | namespace member_detection { 12 | 13 | namespace detail { 14 | 15 | template 16 | using void_t = void; 17 | 18 | template 19 | struct is_container3_helper : false_t { 20 | }; 21 | 22 | template 23 | struct is_container3_helper> : true_t { 24 | }; 25 | 26 | template 27 | constexpr auto is_container4_helper(int) -> decltype(val_of_t(), true) { 28 | return true; 29 | } 30 | 31 | template 32 | constexpr auto is_container4_helper(...) { 33 | return false; 34 | } 35 | 36 | template 37 | void dump(std::ostream& os, T const& val); 38 | 39 | template 40 | void dump(std::ostream& os, T const& val, true_t) { 41 | os << "<<< begin container of type " << typeid(T).name() << " >>>\n"; 42 | for (auto const& elem : val) { 43 | dump(os, elem); 44 | } 45 | os << "<<< end container >>>\n"; 46 | } 47 | 48 | template 49 | void dump(std::ostream& os, T const& val, false_t) { 50 | os << "plain value: " << val << '\n'; 51 | } 52 | 53 | template 54 | void dump(std::ostream& os, T const& val) { 55 | dump(os, val, bool_t::value>{}); 56 | } 57 | 58 | } 59 | 60 | template 61 | struct is_container1 { 62 | 63 | // Two types whose sizes are guaranteed to differ according to The Standard 64 | using when_false_t = short; 65 | using when_true_t = long; 66 | 67 | template static when_false_t test(...); 68 | template static when_true_t test(typename S::iterator*); 69 | 70 | constexpr static bool value = sizeof(test(nullptr)) == sizeof(when_true_t); 71 | 72 | }; 73 | 74 | template 75 | struct is_container2 { 76 | 77 | template 78 | static std::true_type test(S&&); 79 | static std::false_type test(...); 80 | 81 | constexpr static bool value = decltype(test(val_of_t()))::value; 82 | 83 | }; 84 | 85 | template 86 | struct is_container3 : detail::is_container3_helper { 87 | }; 88 | 89 | template 90 | using is_container4 = bool_t(0)>; 91 | 92 | template