Mercurial > lbo > hg > ctmp
changeset 3:58777a883f54
Vastly improve replace_type
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 25 Mar 2020 10:10:30 +0100 |
parents | 20c6c0bec02a |
children | 90fe4346fcbc |
files | CMakeLists.txt src/replace_type.cc |
diffstat | 2 files changed, 59 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Tue Mar 24 19:50:07 2020 +0100 +++ b/CMakeLists.txt Wed Mar 25 10:10:30 2020 +0100 @@ -7,3 +7,5 @@ add_executable(binary src/binary.cc) add_executable(replace_type src/replace_type.cc) + +add_executable(fac src/fac.cc)
--- a/src/replace_type.cc Tue Mar 24 19:50:07 2020 +0100 +++ b/src/replace_type.cc Wed Mar 25 10:10:30 2020 +0100 @@ -1,40 +1,77 @@ #include <iostream> - -class C {}; +#include <type_traits> template<typename C, typename X, typename Y> struct replace_type { typedef C type; }; +// Simple replacement. template<typename X, typename Y> -struct replace_type<X*, X, Y> { - typedef Y* type; -}; - -template<typename X, typename Y> -struct replace_type<X&, X, Y> { - typedef Y& type; +struct replace_type<X, X, Y> { + typedef Y type; }; -template<typename R, typename X, typename Y> -struct replace_type<R (*)(X), X, Y> { - typedef R (*type)(Y); +namespace { + // For pointer/reference types, if C* == X, replace, otherwise continue replacing. + template<bool is_same, typename C, typename X, typename Y> + struct replace_type_ptr_helper { + typedef Y type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<true, C*, X, Y> { + typedef Y type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<false, C*, X, Y> { + typedef typename replace_type<C, X, Y>::type* type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<true, C&, X, Y> { + typedef Y type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<false, C&, X, Y> { + typedef typename replace_type<C, X, Y>::type& type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<true, C&&, X, Y> { + typedef Y type; + }; + template<typename C, typename X, typename Y> + struct replace_type_ptr_helper<false, C&&, X, Y> { + typedef typename replace_type<C, X, Y>::type&& type; + }; +} + +template<typename C, typename X, typename Y> +struct replace_type<C*, X, Y> { + typedef typename replace_type_ptr_helper<std::is_same<C*, X>::value, C*, X, Y>::type type; }; -template<typename X, typename Y> -struct replace_type<X (*)(X), X, Y> { - typedef Y (*type)(Y); +template<typename C, typename X, typename Y> +struct replace_type<C&, X, Y> { + typedef typename replace_type_ptr_helper<std::is_same<C&, X>::value, C&, X, Y>::type type; }; -template<typename A, typename X, typename Y> -struct replace_type<X (*)(A), X, Y> { - typedef Y (*type)(A); +template<typename C, typename X, typename Y> +struct replace_type<C&&, X, Y> { + typedef typename replace_type_ptr_helper<std::is_same<C&&, X>::value, C&&, X, Y>::type type; +}; + +template<typename C, typename X, typename Y> +struct replace_type<const C, X, Y> { + typedef const typename replace_type_ptr_helper<std::is_same<const C, X>::value, const C, X, Y>::type type; +}; + +template<typename R, typename A, typename X, typename Y> +struct replace_type<R (*)(A), X, Y> { + typedef typename replace_type<R, X, Y>::type (*type)(typename replace_type<A, X, Y>::type); }; int main(void) { - typedef char& (*typ)(char& a); + typedef const long long* typ; std::cout << typeid(typ).name() << std::endl; - std::cout << typeid(replace_type<typ, unsigned, unsigned>::type).name() << std::endl; + std::cout << typeid(replace_type<typ, long long, unsigned>::type).name() << std::endl; return 0; }