Chromium Code Reviews| Index: core/include/fxcrt/fx_string.h | 
| diff --git a/core/include/fxcrt/fx_string.h b/core/include/fxcrt/fx_string.h | 
| index 023f7658c3f9c492d077400b28c7626600a27f3e..d31524a202db60fc4f002ed2bcf66d3645ea882c 100644 | 
| --- a/core/include/fxcrt/fx_string.h | 
| +++ b/core/include/fxcrt/fx_string.h | 
| @@ -18,6 +18,14 @@ class CFX_WideString; | 
| struct CFX_CharMap; | 
| typedef int FX_STRSIZE; | 
| +// Technique upon which we build code to allow the compiler to tell | 
| +// the difference between a pointer for which it doesn't know the size, | 
| +// and an array where it does know the size (typically a const char string | 
| +// literal), until std::enable_if becomes available. See also: | 
| +// http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error | 
| +template <typename T, typename U> struct FX_SFINAE { typedef T nonesuch; }; | 
| +template <typename T> struct FX_SFINAE<T, T> { typedef T type; }; | 
| + | 
| // An immutable string with caller-provided storage which must outlive the | 
| // string itself. | 
| class CFX_ByteStringC | 
| @@ -37,11 +45,20 @@ public: | 
| m_Length = size; | 
| } | 
| - CFX_ByteStringC(FX_LPCSTR ptr) | 
| - { | 
| - m_Ptr = (FX_LPCBYTE)ptr; | 
| - m_Length = ptr ? (FX_STRSIZE)FXSYS_strlen(ptr) : 0; | 
| - } | 
| + // For the case where the compiler can't deduce the length. | 
| + template<typename T, typename = typename FX_SFINAE<T, char>::type> | 
| + CFX_ByteStringC(const T* const& ptr) | 
| + : CFX_ByteStringC(ptr, ptr ? (FX_STRSIZE)FXSYS_strlen(ptr) : 0) { } | 
| + | 
| + // For the case where the compiler can deduce the length of a literal. | 
| + template<size_t N> | 
| + CFX_ByteStringC(const char (&ptr)[N]) | 
| + : CFX_ByteStringC(ptr, N - 1) { } | 
| 
 
brucedawson
2015/12/15 00:45:10
I don't think we have any guarantee that this is a
 
 | 
| + | 
| + // For the case where the compiler can deduce the length, but not a literal. | 
| + template<size_t N> | 
| + CFX_ByteStringC(char (&ptr)[N]) | 
| + : CFX_ByteStringC(ptr, ptr ? (FX_STRSIZE)FXSYS_strlen(ptr) : 0) { } | 
| // |ch| must be an lvalue that outlives the the CFX_ByteStringC. However, | 
| // the use of char rvalues are not caught at compile time. They are | 
| @@ -204,11 +221,23 @@ public: | 
| CFX_ByteString(char ch); | 
| - CFX_ByteString(FX_LPCSTR ptr) | 
| + // For the case where the compiler can't deduce the length. | 
| + template<typename T, typename = typename FX_SFINAE<T, char>::type> | 
| + CFX_ByteString(const T* const& ptr) | 
| : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) { } | 
| - CFX_ByteString(FX_LPCSTR ptr, FX_STRSIZE len); | 
| + // For the case where the compiler can deduce the length of a literal. | 
| + template<size_t N> | 
| + CFX_ByteString(const char (&ptr)[N]) | 
| + : CFX_ByteString(ptr, N - 1) { } | 
| + | 
| + // For the case where the compiler can deduce the length, but not a literal. | 
| + template<size_t N> | 
| + CFX_ByteString(char (&ptr)[N]) | 
| + : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) { } | 
| + | 
| + CFX_ByteString(FX_LPCSTR ptr, FX_STRSIZE len); | 
| CFX_ByteString(FX_LPCBYTE ptr, FX_STRSIZE len); | 
| CFX_ByteString(FX_BSTR bstrc); | 
| @@ -463,18 +492,27 @@ public: | 
| m_Length = 0; | 
| } | 
| - CFX_WideStringC(FX_LPCWSTR ptr) | 
| - { | 
| - m_Ptr = ptr; | 
| - m_Length = ptr ? (FX_STRSIZE)FXSYS_wcslen(ptr) : 0; | 
| - } | 
| - | 
| CFX_WideStringC(FX_WCHAR& ch) | 
| { | 
| m_Ptr = &ch; | 
| m_Length = 1; | 
| } | 
| + // For the case where the compiler can't deduce the length. | 
| + template<typename T, typename = typename FX_SFINAE<T, wchar_t>::type> | 
| + CFX_WideStringC(const T* const& ptr) | 
| + : CFX_WideStringC(ptr, ptr ? (FX_STRSIZE)FXSYS_wcslen(ptr) : 0) { } | 
| + | 
| + // For the case where the compiler can deduce the length of a literal. | 
| + template<size_t N> | 
| + CFX_WideStringC(const wchar_t (&ptr)[N]) | 
| + : CFX_WideStringC(ptr, N - 1) { } | 
| + | 
| + // For the case where the compiler can deduce the length, but not a literal. | 
| + template<size_t N> | 
| + CFX_WideStringC(wchar_t (&ptr)[N]) | 
| + : CFX_WideStringC(ptr, ptr ? (FX_STRSIZE)FXSYS_wcslen(ptr) : 0) { } | 
| + | 
| CFX_WideStringC(FX_LPCWSTR ptr, FX_STRSIZE len) | 
| { | 
| m_Ptr = ptr; | 
| @@ -629,7 +667,19 @@ public: | 
| CFX_WideString(const CFX_WideString& str); | 
| - CFX_WideString(FX_LPCWSTR ptr) | 
| + // For the case where the compiler can't deduce the length. | 
| + template<typename T, typename = typename FX_SFINAE<T, wchar_t>::type> | 
| + CFX_WideString(const T* const& ptr) | 
| + : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) { } | 
| + | 
| + // For the case where the compiler can deduce the length of a literal. | 
| + template<size_t N> | 
| + CFX_WideString(const wchar_t (&ptr)[N]) | 
| + : CFX_WideString(ptr, N - 1) { } | 
| + | 
| + // For the case where the compiler can deduce the length, but not a literal. | 
| + template<size_t N> | 
| + CFX_WideString(wchar_t (&ptr)[N]) | 
| : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) { } | 
| CFX_WideString(FX_LPCWSTR ptr, FX_STRSIZE len); |