Skip to content

Instantly share code, notes, and snippets.

@andreaswachowski
Last active August 29, 2015 14:07
Show Gist options
  • Save andreaswachowski/cacbdd5e9ad77599defc to your computer and use it in GitHub Desktop.
Save andreaswachowski/cacbdd5e9ad77599defc to your computer and use it in GitHub Desktop.
Print numeric_limits/size_of for all fundamental types in C++
// Print limits and sizeof information for C++ internal types
//
// This is a nice example of variadic templates and recursion.
#include <limits>
#include <typeinfo>
#include <iostream>
#include <iomanip>
#include "type.h"
using namespace std;
template <typename... Args>
struct Impl;
template <typename First, typename... Args>
struct Impl<First, Args...>
{
static void PrintLimit()
{
static int kMaxTypeWidth {18};
cout << "numeric_limits<" << left << setw(kMaxTypeWidth) << type<First>() << ">::digits: " << setw(2) << numeric_limits<First>::digits
<< "; sizeof(" << setw(kMaxTypeWidth) << type<First>() << "): " << sizeof(First) << endl;
Impl<Args...>::PrintLimit();
}
};
template <>
struct Impl<>
{
static void PrintLimit() { }
};
template <typename... Args>
void PrintLimit()
{
return Impl<Args...>::PrintLimit();
}
int main() {
PrintLimit<
// standard signed integer types
signed char,
short int,
int,
long,
long long,
// standard unsigned integer types
unsigned char,
unsigned short int,
unsigned int,
unsigned long,
unsigned long long,
// Rest
bool,
char,
wchar_t,
char16_t,
char32_t,
// void, commented out, because sizeof cannot be applied to it
nullptr_t,
// Compound types
void*,
int*>();
}
This is a small example for using variadic templates, and template recursion, in C++.
The output of prints limits of a C++ implementation, for example on my machine:
numeric_limits<signed char >::digits: 7 ; sizeof(signed char ): 1
numeric_limits<short >::digits: 15; sizeof(short ): 2
numeric_limits<int >::digits: 31; sizeof(int ): 4
numeric_limits<long >::digits: 63; sizeof(long ): 8
numeric_limits<long long >::digits: 63; sizeof(long long ): 8
numeric_limits<unsigned char >::digits: 8 ; sizeof(unsigned char ): 1
numeric_limits<unsigned short >::digits: 16; sizeof(unsigned short ): 2
numeric_limits<unsigned int >::digits: 32; sizeof(unsigned int ): 4
numeric_limits<unsigned long >::digits: 64; sizeof(unsigned long ): 8
numeric_limits<unsigned long long>::digits: 64; sizeof(unsigned long long): 8
numeric_limits<bool >::digits: 1 ; sizeof(bool ): 1
numeric_limits<char >::digits: 7 ; sizeof(char ): 1
numeric_limits<wchar_t >::digits: 31; sizeof(wchar_t ): 4
numeric_limits<char16_t >::digits: 16; sizeof(char16_t ): 2
numeric_limits<char32_t >::digits: 32; sizeof(char32_t ): 4
numeric_limits<decltype(nullptr) >::digits: 0 ; sizeof(decltype(nullptr) ): 8
numeric_limits<void* >::digits: 0 ; sizeof(void* ): 8
numeric_limits<int* >::digits: 0 ; sizeof(int* ): 8
all: a.out
./a.out
# In case a different compiler than g++ is used, and program-internal demangling via type.h doesn't work,
# use c++filt:
# ./a.out | c++filt -t
a.out: limits.cc type.cc
$(GCC) -std=c++11 limits.cc type.cc
clean:
rm -f ./a.out
#include "type.hpp"
#ifdef __GNUG__
#include <cstdlib>
#include <memory>
#include <cxxabi.h>
// From http://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-infoname
std::string demangle(const char* name) {
int status = -4; // some arbitrary value to eliminate the compiler warning
// enable c++11 by passing the flag -std=c++11 to g++
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name ;
}
#else
// does nothing if not g++
std::string demangle(const char* name) {
return name;
}
#endif
#ifndef TYPE_HPP
#define TYPE_HPP
// From http://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-infoname
#include <string>
#include <typeinfo>
std::string demangle(const char* name);
template <class T>
std::string type() {
return demangle(typeid(T).name());
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment