#include <vector>
#include <utility>
#include <type_traits>
#include <iostream>
#include <iterator>
template <typename Iter>
constexpr bool is_const_iter_v = std::is_const< std::remove_reference_t< typename std::iterator_traits< Iter >::reference > >::value;
template <typename Iter>
using iter_val_t = typename std::iterator_traits< Iter >::value_type;
template <typename Iter, typename T>
constexpr bool is_T_iter_v = std::is_same< iter_val_t< Iter >, T >::value && !is_const_iter_v< Iter >;
template <typename Iter>
constexpr bool is_wchar_iter_v = is_T_iter_v< Iter, wchar_t >;
template <typename Iter, std::enable_if_t < is_T_iter_v< Iter, char >, int > = 0 >
void CalcSomething( Iter begin, Iter end )
{
std::cout << "i'm char\n";
}
template <typename Iter, std::enable_if_t < is_T_iter_v< Iter, char16_t > ||
( is_wchar_iter_v< Iter > && sizeof( wchar_t ) == sizeof( char16_t ) ), int > = 0 >
void CalcSomething( Iter begin, Iter end )
{
std::cout << "i'm char16\n";
}
template <typename Iter, std::enable_if_t < is_T_iter_v< Iter, char32_t > ||
( is_wchar_iter_v< Iter > && sizeof( wchar_t ) == sizeof( char32_t ) ), int > = 0 >
void CalcSomething( Iter begin, Iter end )
{
std::cout << "i'm char32\n";
}
int main()
{
char* p = nullptr;
CalcSomething( p, p );
wchar_t* pw = nullptr;
CalcSomething( pw, pw );
// FAILS TO COMPILE
// const char* cp = nullptr;
// CalcSomething( cp, cp );
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcj4KY29uc3RleHByIGJvb2wgaXNfY29uc3RfaXRlcl92ID0gc3RkOjppc19jb25zdDwgc3RkOjpyZW1vdmVfcmVmZXJlbmNlX3Q8IHR5cGVuYW1lIHN0ZDo6aXRlcmF0b3JfdHJhaXRzPCBJdGVyID46OnJlZmVyZW5jZSA+ID46OnZhbHVlOwoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CnVzaW5nIGl0ZXJfdmFsX3QgPSB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czwgSXRlciA+Ojp2YWx1ZV90eXBlOwoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXIsIHR5cGVuYW1lIFQ+CmNvbnN0ZXhwciBib29sIGlzX1RfaXRlcl92ID0gc3RkOjppc19zYW1lPCBpdGVyX3ZhbF90PCBJdGVyID4sIFQgPjo6dmFsdWUgJiYgIWlzX2NvbnN0X2l0ZXJfdjwgSXRlciA+OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXI+CmNvbnN0ZXhwciBib29sIGlzX3djaGFyX2l0ZXJfdiA9IGlzX1RfaXRlcl92PCBJdGVyLCB3Y2hhcl90ID47Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlciwgc3RkOjplbmFibGVfaWZfdCA8IGlzX1RfaXRlcl92PCBJdGVyLCBjaGFyID4sIGludCA+ID0gMCA+CnZvaWQgQ2FsY1NvbWV0aGluZyggSXRlciBiZWdpbiwgSXRlciBlbmQgKQp7CiAgc3RkOjpjb3V0IDw8ICJpJ20gY2hhclxuIjsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXIsIHN0ZDo6ZW5hYmxlX2lmX3QgPCBpc19UX2l0ZXJfdjwgSXRlciwgY2hhcjE2X3QgPiB8fAogICggaXNfd2NoYXJfaXRlcl92PCBJdGVyID4gJiYgc2l6ZW9mKCB3Y2hhcl90ICkgPT0gc2l6ZW9mKCBjaGFyMTZfdCApICksIGludCA+ID0gMCA+CiAgdm9pZCBDYWxjU29tZXRoaW5nKCBJdGVyIGJlZ2luLCBJdGVyIGVuZCApCnsKICBzdGQ6OmNvdXQgPDwgImknbSBjaGFyMTZcbiI7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBJdGVyLCBzdGQ6OmVuYWJsZV9pZl90IDwgaXNfVF9pdGVyX3Y8IEl0ZXIsIGNoYXIzMl90ID4gfHwKICAoIGlzX3djaGFyX2l0ZXJfdjwgSXRlciA+ICYmIHNpemVvZiggd2NoYXJfdCApID09IHNpemVvZiggY2hhcjMyX3QgKSApLCBpbnQgPiA9IDAgPgogIHZvaWQgQ2FsY1NvbWV0aGluZyggSXRlciBiZWdpbiwgSXRlciBlbmQgKQp7CiAgc3RkOjpjb3V0IDw8ICJpJ20gY2hhcjMyXG4iOwp9CgoKaW50IG1haW4oKSAKewogIGNoYXIqIHAgPSBudWxscHRyOwogIENhbGNTb21ldGhpbmcoIHAsIHAgKTsKCiAgd2NoYXJfdCogcHcgPSBudWxscHRyOwogIENhbGNTb21ldGhpbmcoIHB3LCBwdyApOwoKICAvLyBGQUlMUyBUTyBDT01QSUxFCiAgLy8gY29uc3QgY2hhciogY3AgPSBudWxscHRyOwogIC8vIENhbGNTb21ldGhpbmcoIGNwLCBjcCApOwp9