diff --git a/src/cpputils/container/smart_ptr.h b/src/cpputils/container/smart_ptr.h index 69fcdb4..26692a7 100644 --- a/src/cpputils/container/smart_ptr.h +++ b/src/cpputils/container/smart_ptr.h @@ -16,19 +16,19 @@ namespace utl template struct __impl_cop_is_value : - public mp::c_true { }; + public mp::c_true; template struct __impl_cop_is_value : - public mp::c_false { }; + public mp::c_false; template class F, class X> struct __impl_cop_is_value, mp::enable_if, F>>> : - public mp::c_false { }; + public mp::c_false; template struct __impl_cop_is_value, void> : - public mp::c_false { }; + public mp::c_false; template using cop_is_value = __impl_cop_is_value>; diff --git a/src/cpputils/mp.h b/src/cpputils/mp.h index 2a5525e..1016fc8 100644 --- a/src/cpputils/mp.h +++ b/src/cpputils/mp.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include \ No newline at end of file diff --git a/src/cpputils/mp/container.h b/src/cpputils/mp/container.h index ce813a9..9af1b05 100644 --- a/src/cpputils/mp/container.h +++ b/src/cpputils/mp/container.h @@ -1,3 +1,6 @@ #pragma once -#include \ No newline at end of file +#include +#include +#include +#include diff --git a/src/cpputils/mp/container/basic_tuple.h b/src/cpputils/mp/container/basic_tuple.h new file mode 100644 index 0000000..8e2d1d1 --- /dev/null +++ b/src/cpputils/mp/container/basic_tuple.h @@ -0,0 +1,159 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace utl { +namespace mp { + + struct tag_basic_tuple { }; + + namespace __impl + { + template + struct basic_tuple_index; + + template + struct basic_tuple_impl; + + struct basic_tuple_from_other { }; + + template + struct basic_tuple_impl, Xn...> + : intern::ebo, Xn>... + { + static constexpr size_t _size = sizeof...(Xn); + + constexpr basic_tuple_impl() = default; + + template + explicit constexpr basic_tuple_impl(basic_tuple_from_other, Other&& other) + : intern::ebo, Xn>(intern::ebo_get>(std::forward(other)))... + { } + + template + explicit constexpr basic_tuple_impl(Yn&&... yn) + : intern::ebo, Xn>(std::forward(yn))... + { } + }; + } + + template + struct basic_tuple final + : __impl::basic_tuple_impl, Xn...> + { + using tag = tag_basic_tuple; + using base_type = __impl::basic_tuple_impl, Xn...>; + + constexpr basic_tuple() = default; + + template>>> + constexpr basic_tuple(Other&& other) + : base_type(__impl::basic_tuple_from_other { }, std::forward(other)) + { } + + template + explicit constexpr basic_tuple(Yn&&... yn) + : base_type(std::forward(yn)...) + { } + + template + constexpr auto at(const N& n) const + { return mp::at(*this, n); } + + template + constexpr auto unpack(F&& f) const + { return mp::unpack(*this, std::forward(f)); } + + template + constexpr auto transform(F&& f) const + { return mp::transform(*this, std::forward(f)); } + }; + + constexpr auto make_basic_tuple = make; + + namespace __impl + { + /* tag_of */ + template + struct tag_of_impl> + { using type = tag_basic_tuple; }; + + /* make */ + template<> + struct make_impl + { + template + static constexpr auto apply(Xn&&... xn) + { return basic_tuple...> { std::forward(xn)... }; } + }; + + /* unpack */ + template<> + struct unpack_impl + { + template + static constexpr auto apply(const basic_tuple_impl, Xn...>& xs, F&& f) + { + return std::forward(f)( + intern::ebo_get>( + static_cast, Xn>&>(xs) + )... + ); + } + + template + static constexpr auto apply(basic_tuple_impl, Xn...>& xs, F&& f) + { + return std::forward(f)( + intern::ebo_get>( + static_cast, Xn>&>(xs) + )... + ); + } + + template + static constexpr auto apply(basic_tuple_impl, Xn...>&& xs, F&& f) + { + return std::forward(f)( + intern::ebo_get>( + static_cast, Xn>&&>(xs) + )... + ); + } + }; + + /* at */ + template<> + struct at_impl + { + template + static constexpr auto apply(Xs&& xs, const N&) + { + constexpr size_t index = N::value; + return intern::ebo_get>(std::forward(xs)); + } + }; + } + + template + constexpr auto at_c(const basic_tuple& x) + { return intern::ebo_get<__impl::basic_tuple_index>(x); } + + template + constexpr auto at_c(basic_tuple& x) + { return intern::ebo_get<__impl::basic_tuple_index>(x); } + + template + constexpr auto at_c(basic_tuple&& x) + { return intern::ebo_get<__impl::basic_tuple_index>(std::forward>(x)); } + +} +} \ No newline at end of file diff --git a/src/cpputils/mp/container/map.h b/src/cpputils/mp/container/map.h new file mode 100644 index 0000000..4705b94 --- /dev/null +++ b/src/cpputils/mp/container/map.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +namespace utl { +namespace mp { + + struct tag_map { }; + + constexpr auto make_map = make; + + constexpr auto to_map = make; + + namespace __impl /* forward declaration */ + { + template + struct make_map_type; + } + + template + using map = typename __impl::make_map_type::type; + + namespace __impl /* implementation */ + { + template + struct make_map_type + { + using storage_type = basic_tuple; + + }; + } + +} +} \ No newline at end of file diff --git a/src/cpputils/mp/container/pair.h b/src/cpputils/mp/container/pair.h index 632bf98..8d5353d 100644 --- a/src/cpputils/mp/container/pair.h +++ b/src/cpputils/mp/container/pair.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include #include #include #include @@ -33,6 +33,7 @@ namespace mp { private intern::ebo<__impl::pair_index<0>, First>, private intern::ebo<__impl::pair_index<1>, Second> { + using tag = tag_pair; using this_type = pair; // default constructor diff --git a/src/cpputils/mp/container/type.h b/src/cpputils/mp/container/type.h new file mode 100644 index 0000000..c8e2451 --- /dev/null +++ b/src/cpputils/mp/container/type.h @@ -0,0 +1,268 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace utl { +namespace mp { + + namespace __impl /* forward declaration */ + { + template + struct type_impl; + + struct decl_type_t + { + template + constexpr auto operator()(T&& t) const; + }; + + struct type_id_t + { + template + constexpr auto operator()(T&&) const; + }; + + struct size_of_t + { + template + constexpr auto operator()(T&&) const; + }; + + struct align_of_t + { + template + constexpr auto operator()(T&&) const; + }; + + struct is_valid_type_t + { + template + constexpr auto operator()(F&&) const; + + template + constexpr auto operator()(F&&, Args&&...) const; + }; + + template