I'm not suggesting converting any pointers. What is being
converted is what the pointer argument points at, which is to say
an integer or character type. To illustrate here is a complete
program:
using Byte = unsigned char;
constexpr bool
is_utf8_tail_byte( const char ch ){
return (Byte( ch ) >> 6) == 0b10;
}
template < typename T >
constexpr int
n_code_points( T const* s ){
int n = 0;
while( *s ){
++s;
while( is_utf8_tail_byte( *s ) ){ ++s; }
++n;
}
return n;
}
constexpr char t1[] = "\xE6\xF8\xE5";
constexpr unsigned char t2[] = "\xE6\xF8\xE5";
constexpr signed char t3[] = "\xE6\xF8\xE5";
constexpr unsigned int t4[] = { 0xE6, 0xF8, 0xE5, 0 };
constexpr signed int t5[] = { 0xE6, 0xF8, 0xE5, 0 };
constexpr int n1 = n_code_points( t1 );
constexpr int n2 = n_code_points( t2 );
constexpr int n3 = n_code_points( t3 );
constexpr int n4 = n_code_points( t4 );
constexpr int n5 = n_code_points( t5 );
static char test_n1[ n1 ];
static char test_n2[ n2 ];
static char test_n3[ n3 ];
static char test_n4[ n4 ];
static char test_n5[ n5 ];
#include <cstdio>
int
main(){
constexpr int n = n_code_points( u8"\xE6\xF8\xE5" ); // Should be 3
printf( "n is %d\n", n );
printf( "n1 is %d\n", n1 );
printf( "n2 is %d\n", n2 );
printf( "n3 is %d\n", n3 );
printf( "n4 is %d\n", n4 );
printf( "n5 is %d\n", n5 );
return 0;
}
The program shown compiles and runs in C++14. Its output:
n is 3
n1 is 3
n2 is 3
n3 is 3
n4 is 3
n5 is 3
Does this approach do what you want? If not then how doesn't it?