Third step in moving towards adopting new timer semantics
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 944c499..5f22510 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,7 +3,8 @@
# Define the source files
set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc"
- "log.cc" "sleep.cc" "sysinfo.cc" "walltime.cc")
+ "log.cc" "sleep.cc" "string_util.cc" "sysinfo.cc"
+ "walltime.cc")
# Determine the correct regular expression engine to use
if(HAVE_STD_REGEX)
set(RE_FILES "re_std.cc")
diff --git a/src/benchmark.cc b/src/benchmark.cc
index 97464c0..3ce37fd 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
#include "re.h"
#include "sleep.h"
#include "stat.h"
+#include "string_util.h"
#include "sysinfo.h"
#include "walltime.h"
@@ -82,108 +83,6 @@
namespace benchmark {
namespace {
-// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
-const char kBigSIUnits[] = "kMGTPEZY";
-// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.
-const char kBigIECUnits[] = "KMGTPEZY";
-// milli, micro, nano, pico, femto, atto, zepto, yocto.
-const char kSmallSIUnits[] = "munpfazy";
-
-// We require that all three arrays have the same size.
-static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),
- "SI and IEC unit arrays must be the same size");
-static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
- "Small SI and Big SI unit arrays must be the same size");
-static const size_t kUnitsSize = arraysize(kBigSIUnits);
-
-void ToExponentAndMantissa(double val, double thresh, int precision,
- double one_k, std::string* mantissa, size_t* exponent) {
- std::stringstream mantissa_stream;
-
- if (val < 0) {
- mantissa_stream << "-";
- val = -val;
- }
-
- // Adjust threshold so that it never excludes things which can't be rendered
- // in 'precision' digits.
- const double adjusted_threshold =
- std::max(thresh, 1.0 / pow(10.0, precision));
- const double big_threshold = adjusted_threshold * one_k;
- const double small_threshold = adjusted_threshold;
-
- if (val > big_threshold) {
- // Positive powers
- double scaled = val;
- for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {
- scaled /= one_k;
- if (scaled <= big_threshold) {
- mantissa_stream << scaled;
- *exponent = i + 1;
- *mantissa = mantissa_stream.str();
- return;
- }
- }
- mantissa_stream << val;
- *exponent = 0;
- } else if (val < small_threshold) {
- // Negative powers
- double scaled = val;
- for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {
- scaled *= one_k;
- if (scaled >= small_threshold) {
- mantissa_stream << scaled;
- *exponent = -i - 1;
- *mantissa = mantissa_stream.str();
- return;
- }
- }
- mantissa_stream << val;
- *exponent = 0;
- } else {
- mantissa_stream << val;
- *exponent = 0;
- }
- *mantissa = mantissa_stream.str();
-}
-
-std::string ExponentToPrefix(size_t exponent, bool iec) {
- if (exponent == 0) return "";
-
- const size_t index = (exponent > 0 ? exponent - 1 : -exponent - 1);
- if (index >= kUnitsSize) return "";
-
- const char* array =
- (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);
- if (iec)
- return array[index] + std::string("i");
- else
- return std::string(1, array[index]);
-}
-
-std::string ToBinaryStringFullySpecified(double value, double threshold,
- int precision) {
- std::string mantissa;
- size_t exponent;
- ToExponentAndMantissa(value, threshold, precision, 1024.0, &mantissa,
- &exponent);
- return mantissa + ExponentToPrefix(exponent, false);
-}
-
-inline void AppendHumanReadable(int n, std::string* str) {
- std::stringstream ss;
- // Round down to the nearest SI prefix.
- ss << "/" << ToBinaryStringFullySpecified(n, 1.0, 0);
- *str += ss.str();
-}
-
-inline std::string HumanReadableNumber(double n) {
- // 1.1 means that figures up to 1.1k should be shown with the next unit down;
- // this softens edge effects.
- // 1 means that we should show one decimal place of precision.
- return ToBinaryStringFullySpecified(n, 1.1, 1);
-}
-
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
static const int kRangeMultiplier = 8;
@@ -271,7 +170,7 @@
mean_data->iterations;
mean_data->bytes_per_second = bytes_per_second_stat.Mean();
mean_data->items_per_second = items_per_second_stat.Mean();
- mean_data->max_heapbytes_used = max_heapbytes_used_stat.max();
+ mean_data->max_heapbytes_used = max_heapbytes_used_stat.Max();
// Only add label to mean/stddev if it is same for all runs
mean_data->report_label = reports[0].report_label;
diff --git a/src/colorprint.cc b/src/colorprint.cc
index 3a84f6a..783797b 100644
--- a/src/colorprint.cc
+++ b/src/colorprint.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,9 +14,10 @@
#include "colorprint.h"
-#include <stdarg.h>
+#include <cstdarg>
#include "commandlineflags.h"
+#include "internal_macros.h"
DECLARE_bool(color_print);
diff --git a/src/commandlineflags.cc b/src/commandlineflags.cc
index 57a75f5..f2b1913 100644
--- a/src/commandlineflags.cc
+++ b/src/commandlineflags.cc
@@ -14,8 +14,7 @@
#include "commandlineflags.h"
-#include <string.h>
-
+#include <cstring>
#include <iostream>
#include <limits>
@@ -75,10 +74,7 @@
}
inline const char* GetEnv(const char* name) {
-#if GTEST_OS_WINDOWS_MOBILE
- // We are on Windows CE, which has no environment variables.
- return NULL;
-#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+#if defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// Environment variables which we programmatically clear will be set to the
// empty string rather than unset (NULL). Handle that case.
const char* const env = getenv(name);
diff --git a/src/commandlineflags.h b/src/commandlineflags.h
index 001c8ba..34b9c6f 100644
--- a/src/commandlineflags.h
+++ b/src/commandlineflags.h
@@ -1,8 +1,7 @@
#ifndef BENCHMARK_COMMANDLINEFLAGS_H_
#define BENCHMARK_COMMANDLINEFLAGS_H_
-#include <stdint.h>
-
+#include <cstdint>
#include <string>
// Macro for referencing flags.
@@ -72,6 +71,6 @@
// Returns true if the string matches the flag.
bool IsFlag(const char* str, const char* flag);
-} // end namespace gbenchmark
+} // end namespace benchmark
#endif // BENCHMARK_COMMANDLINEFLAGS_H_
diff --git a/src/cycleclock.h b/src/cycleclock.h
index 0ad430f..5b28417 100644
--- a/src/cycleclock.h
+++ b/src/cycleclock.h
@@ -21,7 +21,10 @@
#ifndef BENCHMARK_CYCLECLOCK_H_
#define BENCHMARK_CYCLECLOCK_H_
-#include <stdint.h>
+#include <cstdint>
+
+#include "benchmark/macros.h"
+#include "internal_macros.h"
#if defined(OS_MACOSX)
#include <mach/mach_time.h>
@@ -39,8 +42,6 @@
#endif
#include <sys/time.h>
-#include "benchmark/macros.h"
-
namespace benchmark {
// NOTE: only i386 and x86_64 have been well tested.
// PPC, sparc, alpha, and ia64 are based on
diff --git a/src/re.h b/src/re.h
index a2e9fdf..54117b1 100644
--- a/src/re.h
+++ b/src/re.h
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/re_posix.cc b/src/re_posix.cc
index 30e248c..e8fe1fc 100644
--- a/src/re_posix.cc
+++ b/src/re_posix.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/src/re_std.cc b/src/re_std.cc
index 30883fd..cfd7a21 100644
--- a/src/re_std.cc
+++ b/src/re_std.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include <benchmark/macros.h>
#include "re.h"
namespace benchmark {
diff --git a/src/sleep.cc b/src/sleep.cc
index 572d04d..4dfb4d9 100644
--- a/src/sleep.cc
+++ b/src/sleep.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,8 +14,10 @@
#include "sleep.h"
-#include <time.h>
-#include <errno.h>
+#include <cerrno>
+#include <ctime>
+
+#include "internal_macros.h"
namespace benchmark {
#ifdef OS_WINDOWS
diff --git a/src/sleep.h b/src/sleep.h
index 4e877bf..f1e515c 100644
--- a/src/sleep.h
+++ b/src/sleep.h
@@ -1,7 +1,7 @@
#ifndef BENCHMARK_SLEEP_H_
#define BENCHMARK_SLEEP_H_
-#include <stdint.h>
+#include <cstdint>
namespace benchmark {
const int64_t kNumMillisPerSecond = 1000LL;
diff --git a/src/stat.h b/src/stat.h
index b556309..435743c 100644
--- a/src/stat.h
+++ b/src/stat.h
@@ -1,11 +1,12 @@
#ifndef BENCHMARK_STAT_H_
#define BENCHMARK_STAT_H_
-#include <math.h>
-#include <iostream>
+#include <cmath>
+#include <ostream>
#include <limits>
namespace benchmark {
+
template <typename VType, typename NumType>
class Stat1;
@@ -103,7 +104,7 @@
NumType numSamples() const { return numsamples_; }
// Return the sum of this sample set
- VType sum() const { return sum_; }
+ VType Sum() const { return sum_; }
// Return the mean of this sample set
VType Mean() const {
@@ -267,9 +268,9 @@
Self operator*(const VType &k) const { return Self(*this) *= k; }
// Return the maximal value in this sample set
- VType max() const { return max_; }
+ VType Max() const { return max_; }
// Return the minimal value in this sample set
- VType min() const { return min_; }
+ VType Min() const { return min_; }
private:
// The - operation makes no sense with Min/Max
diff --git a/src/string_util.cc b/src/string_util.cc
new file mode 100644
index 0000000..1be1534
--- /dev/null
+++ b/src/string_util.cc
@@ -0,0 +1,157 @@
+#include "string_util.h"
+
+#include <cmath>
+#include <cstdarg>
+#include <array>
+#include <memory>
+#include <sstream>
+
+#include "arraysize.h"
+
+namespace benchmark {
+namespace {
+
+// kilo, Mega, Giga, Tera, Peta, Exa, Zetta, Yotta.
+const char kBigSIUnits[] = "kMGTPEZY";
+// Kibi, Mebi, Gibi, Tebi, Pebi, Exbi, Zebi, Yobi.
+const char kBigIECUnits[] = "KMGTPEZY";
+// milli, micro, nano, pico, femto, atto, zepto, yocto.
+const char kSmallSIUnits[] = "munpfazy";
+
+// We require that all three arrays have the same size.
+static_assert(arraysize(kBigSIUnits) == arraysize(kBigIECUnits),
+ "SI and IEC unit arrays must be the same size");
+static_assert(arraysize(kSmallSIUnits) == arraysize(kBigSIUnits),
+ "Small SI and Big SI unit arrays must be the same size");
+
+static const int kUnitsSize = arraysize(kBigSIUnits);
+
+} // end anonymous namespace
+
+void ToExponentAndMantissa(double val, double thresh, int precision,
+ double one_k, std::string* mantissa,
+ int* exponent) {
+ std::stringstream mantissa_stream;
+
+ if (val < 0) {
+ mantissa_stream << "-";
+ val = -val;
+ }
+
+ // Adjust threshold so that it never excludes things which can't be rendered
+ // in 'precision' digits.
+ const double adjusted_threshold =
+ std::max(thresh, 1.0 / std::pow(10.0, precision));
+ const double big_threshold = adjusted_threshold * one_k;
+ const double small_threshold = adjusted_threshold;
+
+ if (val > big_threshold) {
+ // Positive powers
+ double scaled = val;
+ for (size_t i = 0; i < arraysize(kBigSIUnits); ++i) {
+ scaled /= one_k;
+ if (scaled <= big_threshold) {
+ mantissa_stream << scaled;
+ *exponent = i + 1;
+ *mantissa = mantissa_stream.str();
+ return;
+ }
+ }
+ mantissa_stream << val;
+ *exponent = 0;
+ } else if (val < small_threshold) {
+ // Negative powers
+ double scaled = val;
+ for (size_t i = 0; i < arraysize(kSmallSIUnits); ++i) {
+ scaled *= one_k;
+ if (scaled >= small_threshold) {
+ mantissa_stream << scaled;
+ *exponent = -i - 1;
+ *mantissa = mantissa_stream.str();
+ return;
+ }
+ }
+ mantissa_stream << val;
+ *exponent = 0;
+ } else {
+ mantissa_stream << val;
+ *exponent = 0;
+ }
+ *mantissa = mantissa_stream.str();
+}
+
+std::string ExponentToPrefix(int exponent, bool iec) {
+ if (exponent == 0) return "";
+
+ const int index = (exponent > 0 ? exponent - 1 : -exponent - 1);
+ if (index >= kUnitsSize) return "";
+
+ const char* array =
+ (exponent > 0 ? (iec ? kBigIECUnits : kBigSIUnits) : kSmallSIUnits);
+ if (iec)
+ return array[index] + std::string("i");
+ else
+ return std::string(1, array[index]);
+}
+
+std::string ToBinaryStringFullySpecified(double value, double threshold,
+ int precision) {
+ std::string mantissa;
+ int exponent;
+ ToExponentAndMantissa(value, threshold, precision, 1024.0, &mantissa,
+ &exponent);
+ return mantissa + ExponentToPrefix(exponent, false);
+}
+
+void AppendHumanReadable(int n, std::string* str) {
+ std::stringstream ss;
+ // Round down to the nearest SI prefix.
+ ss << "/" << ToBinaryStringFullySpecified(n, 1.0, 0);
+ *str += ss.str();
+}
+
+std::string HumanReadableNumber(double n) {
+ // 1.1 means that figures up to 1.1k should be shown with the next unit down;
+ // this softens edge effects.
+ // 1 means that we should show one decimal place of precision.
+ return ToBinaryStringFullySpecified(n, 1.1, 1);
+}
+
+std::string StringPrintFImp(const char *msg, va_list args)
+{
+ // we might need a second shot at this, so pre-emptivly make a copy
+ va_list args_cp;
+ va_copy(args_cp, args);
+
+ // TODO(ericwf): use std::array for first attempt to avoid one memory
+ // allocation guess what the size might be
+ std::array<char, 256> local_buff;
+ std::size_t size = local_buff.size();
+ auto ret = std::vsnprintf(local_buff.data(), size, msg, args_cp);
+
+ va_end(args_cp);
+
+ // handle empty expansion
+ if (ret == 0)
+ return std::string{};
+ if (static_cast<std::size_t>(ret) < size)
+ return std::string(local_buff.data());
+
+ // we did not provide a long enough buffer on our first attempt.
+ // add 1 to size to account for null-byte in size cast to prevent overflow
+ size = static_cast<std::size_t>(ret) + 1;
+ auto buff_ptr = std::unique_ptr<char[]>(new char[size]);
+ ret = std::vsnprintf(buff_ptr.get(), size, msg, args);
+ return std::string(buff_ptr.get());
+}
+
+std::string StringPrintF(const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ std::string tmp = StringPrintFImp(format, args);
+ va_end(args);
+ return tmp;
+}
+
+} // end namespace benchmark
diff --git a/src/string_util.h b/src/string_util.h
new file mode 100644
index 0000000..56018d5
--- /dev/null
+++ b/src/string_util.h
@@ -0,0 +1,48 @@
+#ifndef BENCHMARK_STRING_UTIL_H
+#define BENCHMARK_STRING_UTIL_H
+
+#include <string>
+#include <sstream>
+#include <utility>
+
+namespace benchmark {
+
+void ToExponentAndMantissa(double val, double thresh, int precision,
+ double one_k, std::string* mantissa, int* exponent);
+
+std::string ExponentToPrefix(int exponent, bool iec);
+
+std::string ToBinaryStringFullySpecified(double value, double threshold,
+ int precision);
+
+void AppendHumanReadable(int n, std::string* str);
+
+std::string HumanReadableNumber(double n);
+
+std::string StringPrintF(const char* format, ...);
+
+inline std::ostream&
+StringCatImp(std::ostream& out) noexcept
+{
+ return out;
+}
+
+template <class First, class ...Rest>
+inline std::ostream&
+StringCatImp(std::ostream& out, First&& f, Rest&&... rest)
+{
+ out << std::forward<First>(f);
+ return StringCatImp(out, std::forward<Rest>(rest)...);
+}
+
+template<class ...Args>
+inline std::string StrCat(Args&&... args)
+{
+ std::ostringstream ss;
+ StringCatImp(ss, std::forward<Args>(args)...);
+ return ss.str();
+}
+
+} // end namespace benchmark
+
+#endif // BENCHMARK_STRING_UTIL_H
\ No newline at end of file
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index a67662c..521acb0 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -14,24 +14,26 @@
#include "sysinfo.h"
-#include <errno.h>
#include <fcntl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/resource.h>
#include <sys/types.h> // this header must be included before 'sys/sysctl.h' to avoid compilation error on FreeBSD
#include <sys/sysctl.h>
#include <sys/time.h>
#include <unistd.h>
+#include <cerrno>
+#include <cstdio>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
#include <iostream>
#include <limits>
#include <mutex>
+#include "arraysize.h"
#include "check.h"
#include "cycleclock.h"
+#include "internal_macros.h"
#include "sleep.h"
namespace benchmark {
diff --git a/test/re_test.cc b/test/re_test.cc
index 27bf607..1bba661 100644
--- a/test/re_test.cc
+++ b/test/re_test.cc
@@ -1,4 +1,4 @@
-// Copyright 2014 Google Inc. All rights reserved.
+// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.