Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1597)

Unified Diff: core/include/fxcrt/fx_string.h

Issue 1114313006: Make constructors recognize char[n] vs. char* and avoid strlen calls. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Delegated constructors everywhere. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | core/src/fpdfdoc/doc_basic.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « no previous file | core/src/fpdfdoc/doc_basic.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698