Skip to content

Instantly share code, notes, and snippets.

@DBJDBJ
Last active March 22, 2024 18:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DBJDBJ/b449c9e7bb3e4203b196099a34b45174 to your computer and use it in GitHub Desktop.
Save DBJDBJ/b449c9e7bb3e4203b196099a34b45174 to your computer and use it in GitHub Desktop.
c++ Type confusion stopper. A.k.a -- Reduce compound type to base type
// (c) 2019/2020 by dbj@dbj.org
// CC BY SA 4.0
//
// https://wandbox.org/permlink/h8BE47pvLlBMy7wy
// clang++ prog.cc -std=c++14
// OK for C++14, C++17, C++2a
//
// https://dbj.org/c-reduce-compound-to-base-type/
//
#include <iostream>
#include <string>
namespace dbj
{
#if __cplusplus < 201703L
// for C++14
// inline variables are a C++17 extension too
template< class T, class U >
static constexpr bool is_same_v = std::is_same<T, U>::value;
#endif
template <typename T> struct remove_all_ptr { typedef T type; };
template <typename T> struct remove_all_ptr<T*> {
using type = typename remove_all_ptr<std::remove_cv_t<T>>::type;
};
template <typename T>
using remove_all_ptr_t = typename remove_all_ptr<T>::type ;
template< class T >
struct remove_cvref {
typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
template <class T>
using to_base_t =
remove_all_ptr_t< std::remove_all_extents_t< remove_cvref_t < T > > >;
} // dbj
//////////////////////////////////////////////////////////////////////////////////////
//
// use cases are the proof of usefulness
// feel free to add your own
//
//////////////////////////////////////////////////////////////////////////////////////
// char is base type, deduced from six levels of pointers to char
static_assert(dbj::is_same_v<char ,dbj::to_base_t<char ******>>, "Failed!" );
// std::string is base type for array of pointers to std::string
static_assert(dbj::is_same_v<std::string ,dbj::to_base_t<std::string * (&)[]>>, "Failed!" );
// void () function
static_assert(dbj::is_same_v<void (), dbj::to_base_t<void ()>>, "Failed!") ;
struct X { char data{}; char method () const { return {};} };
// base type is X for an reference to array of X
static_assert(dbj::is_same_v<X, dbj::to_base_t<X (&) []>>, "Failed!" );
// pointer to method on X
using method_t = char (X::*)() ;
// base type is that metod, deduced from an ref to the array of nethod pointers
static_assert(dbj::is_same_v<method_t, dbj::to_base_t< method_t (&) []>>, "Failed!" );
int main( int argc, char ** argv )
{
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment