Functions to print the equivalent uniform initialization expression of a value.
Implemented so far for these types:
#include <vector>
#include <iostream>
#include <string>
#include <set>
#include <map>
#include <type_traits>
template<class CharType, class CharTraits, class YourType>
void PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os, const YourType& v)
{
static_assert(false, "especialize this function for your type!");
}
template<class CharType, class CharTraits, class T>
typename std::enable_if<std::is_integral<T>::value, void>::type
PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os, const T& v)
{
os << v;
}
char PrintL(char){ return '\0';}
char PrintL(wchar_t) { return 'L'; }
template<class CharType, class CharTraits>
void PrintUniformInitialization(std::basic_ostream<char, CharTraits> & os, const std::basic_string<CharType>& v)
{
os << PrintL((CharType) 0) << '"';
for (size_t i = 0; i < v.size(); i++)
{
os << (char) v[i]; //TODO ranges
}
os << '"';
}
template<class CharType, class CharTraits>
void PrintUniformInitialization(std::basic_ostream<wchar_t, CharTraits> & os, const std::basic_string<CharType>& v)
{
os << PrintL((CharType) 0) << '"';
for (size_t i = 0; i < v.size(); i++)
{
os << (wchar_t) v[i]; //TODO ranges
}
os << L'"';
}
template<class CharTraits>
void PrintUniformInitialization(std::basic_ostream<char, CharTraits> & os, bool v)
{
os << (v ? "true" : "false");
}
template<class CharTraits>
void PrintUniformInitialization(std::basic_ostream<wchar_t, CharTraits> & os, bool v)
{
os << (v ? L"true" : L"false");
}
template<class CharType, class CharTraits, class Iterator>
void PrintSequence(std::basic_ostream<CharType, CharTraits> & os,
Iterator beginIt,
Iterator endIt)
{
typedef typename Iterator::value_type T;
os << (CharType)'{';
auto it = beginIt;
if (it != endIt)
{
PrintUniformInitialization(os, *it);
++it;
}
for (; it != endIt; it++)
{
os << (CharType) ',' << (CharType) ' ';
PrintUniformInitialization(os, *it);
}
os << (CharType)'}';
}
template<class CharType, class CharTraits, class T, class TAllocator>
void PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os,
const std::vector<T, TAllocator>& v)
{
PrintSequence(os, v.cbegin(), v.cend());
}
template<class CharType, class CharTraits, class T, class TComp, class TAllocator>
void PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os,
const std::set<T, TComp, TAllocator>& v)
{
PrintSequence(os, v.cbegin(), v.cend());
}
template < class CharType,
class CharTraits,
class _Kty,
class _Ty,
class _Pr,
class _Alloc >
void PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os,
const std::map<_Kty, _Ty, _Pr, _Alloc>& m)
{
os << (CharType)'{';
auto it = m.cbegin();
if (it != m.cend())
{
os << (CharType)'{';
PrintUniformInitialization(os, it->first);
os << (CharType)',' << (CharType)' ';
PrintUniformInitialization(os, it->second);
os << (CharType)'}';
++it;
}
for (; it != m.cend(); it++)
{
os << (CharType)',' << (CharType)' ';
os << (CharType)'{';
PrintUniformInitialization(os, it->first);
os << (CharType)',' << (CharType)' ';
PrintUniformInitialization(os, it->second);
os << (CharType)'}';
}
os << (CharType)'}';
}
//Printing the type name
template<class T>
void PrintTypeName(std::ostream& , T*)
{
static_assert(false, "overload for your type");
}
void PrintTypeName(std::ostream& os, std::wstring*) { os << "std::wstring";}
void PrintTypeName(std::ostream& os, std::string*) { os << "std::string";}
void PrintTypeName(std::ostream& os, int*) { os << "int"; }
void PrintTypeName(std::ostream& os, double*) { os << "double"; }
void PrintTypeName(std::ostream& os, bool*) { os << "bool"; }
void PrintTypeName(std::ostream& os, char*) { os << "char"; }
template<class T>
void PrintTypeName(std::ostream& os, std::vector<T>*)
{
os << "std::vector<";
PrintTypeName(os, (T*)nullptr);
os << ">";
}
template<class T>
void PrintTypeName(std::ostream& os, std::set<T>*)
{
os << "std::set<";
PrintTypeName(os, (T*)nullptr);
os << ">";
}
template<class K, class T>
void PrintTypeName(std::ostream& os, std::map<T, K>*)
{
os << "std::map<";
PrintTypeName(os, (K*)nullptr);
os << ", ";
PrintTypeName(os, (T*)nullptr);
os << ">";
}
Sample:
struct MyType
{
std::wstring x;
bool v;
};
template<class CharType, class CharTraits>
void PrintUniformInitialization(std::basic_ostream<CharType, CharTraits> & os, const MyType& v)
{
os << (CharType)'{';
PrintUniformInitialization(os, v.x);
os << (CharType)',' << (CharType)' ';
PrintUniformInitialization(os, v.v);
os << (CharType)'}';
}
void PrintTypeName(std::ostream& os, MyType*)
{
os << "MyType";
}
template<class CharType, class CharTraits, class T>
void PrintUniformInitializationLn(std::basic_ostream<CharType, CharTraits> & os, const T& v)
{
PrintTypeName(os, (T*)nullptr);
os << std::endl;
PrintUniformInitialization(os, v);
os << std::endl;
os << std::endl;
}
int main()
{
using namespace std;
vector<MyType> vx;
MyType x;
x.v = false;
vx.push_back(x);
PrintUniformInitializationLn(cout, vx);
map<std::wstring, bool> m;
m[L"a"] = true;
m[L"b"] = false;
PrintUniformInitializationLn(cout, m);
std::vector<std::vector<int>> v;
v.push_back(std::vector<int>(2));
v.push_back(std::vector<int>(3));
PrintUniformInitializationLn(cout, m);
std::set<std::wstring> st;
st.insert(L"aa");
st.insert(L"bb");
PrintUniformInitializationLn(cout, st);
std::vector<bool> vb;
vb.push_back(false);
vb.push_back(true);
PrintUniformInitializationLn(cout, vb);
}
Output: ```
std::vector
std::map
std::map
std::setstd::wstring {L"aa", L"bb"}
std::vector