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

Side by Side Diff: base/strings/safe_sprintf.cc

Issue 1467003002: Switch to static_assert in base/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: / Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « base/rand_util.cc ('k') | base/strings/string16.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/strings/safe_sprintf.h" 5 #include "base/strings/safe_sprintf.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include <limits> 10 #include <limits>
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 namespace { 65 namespace {
66 const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1; 66 const size_t kSSizeMaxConst = ((size_t)(ssize_t)-1) >> 1;
67 67
68 const char kUpCaseHexDigits[] = "0123456789ABCDEF"; 68 const char kUpCaseHexDigits[] = "0123456789ABCDEF";
69 const char kDownCaseHexDigits[] = "0123456789abcdef"; 69 const char kDownCaseHexDigits[] = "0123456789abcdef";
70 } 70 }
71 71
72 #if defined(NDEBUG) 72 #if defined(NDEBUG)
73 // We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(), 73 // We would like to define kSSizeMax as std::numeric_limits<ssize_t>::max(),
74 // but C++ doesn't allow us to do that for constants. Instead, we have to 74 // but C++ doesn't allow us to do that for constants. Instead, we have to
75 // use careful casting and shifting. We later use a COMPILE_ASSERT to 75 // use careful casting and shifting. We later use a static_assert to
76 // verify that this worked correctly. 76 // verify that this worked correctly.
77 namespace { 77 namespace {
78 const size_t kSSizeMax = kSSizeMaxConst; 78 const size_t kSSizeMax = kSSizeMaxConst;
79 } 79 }
80 #else // defined(NDEBUG) 80 #else // defined(NDEBUG)
81 // For efficiency, we really need kSSizeMax to be a constant. But for unit 81 // For efficiency, we really need kSSizeMax to be a constant. But for unit
82 // tests, it should be adjustable. This allows us to verify edge cases without 82 // tests, it should be adjustable. This allows us to verify edge cases without
83 // having to fill the entire available address space. As a compromise, we make 83 // having to fill the entire available address space. As a compromise, we make
84 // kSSizeMax adjustable in debug builds, and then only compile that particular 84 // kSSizeMax adjustable in debug builds, and then only compile that particular
85 // part of the unit test in debug builds. 85 // part of the unit test in debug builds.
(...skipping 17 matching lines...) Expand all
103 public: 103 public:
104 // |buffer| is caller-allocated storage that SafeSPrintf() writes to. It 104 // |buffer| is caller-allocated storage that SafeSPrintf() writes to. It
105 // has |size| bytes of writable storage. It is the caller's responsibility 105 // has |size| bytes of writable storage. It is the caller's responsibility
106 // to ensure that the buffer is at least one byte in size, so that it fits 106 // to ensure that the buffer is at least one byte in size, so that it fits
107 // the trailing NUL that will be added by the destructor. The buffer also 107 // the trailing NUL that will be added by the destructor. The buffer also
108 // must be smaller or equal to kSSizeMax in size. 108 // must be smaller or equal to kSSizeMax in size.
109 Buffer(char* buffer, size_t size) 109 Buffer(char* buffer, size_t size)
110 : buffer_(buffer), 110 : buffer_(buffer),
111 size_(size - 1), // Account for trailing NUL byte 111 size_(size - 1), // Account for trailing NUL byte
112 count_(0) { 112 count_(0) {
113 // The following assertion does not build on Mac and Android. This is because 113 // MSVS2013's standard library doesn't mark max() as constexpr yet. cl.exe
114 // static_assert only works with compile-time constants, but mac uses 114 // supports static_cast but doesn't really implement constexpr yet so it doesn't
115 // libstdc++4.2 and android uses stlport, which both don't mark 115 // complain, but clang does.
116 // numeric_limits::max() as constexp. Likewise, MSVS2013's standard library 116 #if __cplusplus >= 201103 && !(defined(__clang__) && defined(OS_WIN))
117 // also doesn't mark max() as constexpr yet. cl.exe supports static_cast but 117 static_assert(kSSizeMaxConst ==
118 // doesn't really implement constexpr yet so it doesn't complain, but clang 118 static_cast<size_t>(std::numeric_limits<ssize_t>::max()),
119 // does. 119 "kSSizeMaxConst should be the max value of an ssize_t");
120 #if __cplusplus >= 201103 && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \
121 !defined(OS_IOS) && !(defined(__clang__) && defined(OS_WIN))
122 COMPILE_ASSERT(kSSizeMaxConst == \
123 static_cast<size_t>(std::numeric_limits<ssize_t>::max()),
124 kSSizeMax_is_the_max_value_of_an_ssize_t);
125 #endif 120 #endif
126 DEBUG_CHECK(size > 0); 121 DEBUG_CHECK(size > 0);
127 DEBUG_CHECK(size <= kSSizeMax); 122 DEBUG_CHECK(size <= kSSizeMax);
128 } 123 }
129 124
130 ~Buffer() { 125 ~Buffer() {
131 // The code calling the constructor guaranteed that there was enough space 126 // The code calling the constructor guaranteed that there was enough space
132 // to store a trailing NUL -- and in debug builds, we are actually 127 // to store a trailing NUL -- and in debug builds, we are actually
133 // verifying this with DEBUG_CHECK()s in the constructor. So, we can 128 // verifying this with DEBUG_CHECK()s in the constructor. So, we can
134 // always unconditionally write the NUL byte in the destructor. We do not 129 // always unconditionally write the NUL byte in the destructor. We do not
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 DEBUG_CHECK(src[0] != '%' || src[1] == '%'); 674 DEBUG_CHECK(src[0] != '%' || src[1] == '%');
680 if (src[0] == '%' && src[1] == '%') { 675 if (src[0] == '%' && src[1] == '%') {
681 ++src; 676 ++src;
682 } 677 }
683 } 678 }
684 return buffer.GetCount(); 679 return buffer.GetCount();
685 } 680 }
686 681
687 } // namespace strings 682 } // namespace strings
688 } // namespace base 683 } // namespace base
OLDNEW
« no previous file with comments | « base/rand_util.cc ('k') | base/strings/string16.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698