<div dir="ltr">Hi Ben,<div><br></div><div>I checked in a similar fix in r277512.</div><div><br></div><div>Please let me know if it helps. This "benchmark" stuff is still immature so non-production worthy patches are always welcome.</div><div><br></div><div>/Eric</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 1, 2016 at 1:45 PM, Craig, Ben <span dir="ltr"><<a href="mailto:ben.craig@codeaurora.org" target="_blank">ben.craig@codeaurora.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The current setup for the benchmark tests don't work well when the compiler being used isn't the system compiler.  I'm on a system with a gcc 4.6.3 installation.  I typically put clang in my path and set CMAKE_CXX_COMPILER and CMAKE_C_COMPILER.  I don't know cmake well enough to recommend the "correct" solution, but these are some (not production worthy) changes that I made locally so that I could build the benchmarks.<br>
<br>
diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt<br>
index e95bfa8..21bc0a8 100644<br>
--- a/benchmarks/CMakeLists.txt<br>
+++ b/benchmarks/CMakeLists.txt<br>
@@ -26,7 +26,9 @@ ExternalProject_Add(google-benchmark-libcxx<br>
         PREFIX benchmark-libcxx<br>
         SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark<br>
         INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx<br>
-        CMAKE_CACHE_DEFAULT_ARGS<br>
+        CMAKE_CACHE_ARGS<br>
+          -DCMAKE_CXX_COMPILER:STRING=clang++<br>
+          -DCMAKE_C_COMPILER:STRING=clang<br>
           -DCMAKE_BUILD_TYPE:STRING=RELEASE<br>
           -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR><br>
-DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS}<br>
@@ -60,6 +62,7 @@ set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native)<br>
 set(BENCHMARK_TEST_COMPILE_FLAGS<br>
     -std=c++14 -O2<br>
     -I${BENCHMARK_LIBCXX_INSTALL}/include<br>
+    -cxx-isystem ${LIBCXX_SOURCE_DIR}/include<br>
 )<br>
 set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS<br>
     -nostdinc++<br>
<br>
<br>
On 7/19/2016 6:07 PM, Eric Fiselier via cfe-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: ericwf<br>
Date: Tue Jul 19 18:07:03 2016<br>
New Revision: 276049<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=276049&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=276049&view=rev</a><br>
Log:<br>
[libcxx] Add support for benchmark tests using Google Benchmark.<br>
<br>
Summary:<br>
This patch does the following:<br>
<br>
1. Checks in a copy of the Google Benchmark library into the libc++ repo under `utils/google-benchmark`.<br>
2. Teaches libc++ how to build Google Benchmark against both (A) in-tree libc++ and (B) the platforms native STL.<br>
3. Allows performance benchmarks to be built as part of the libc++ build.<br>
<br>
Building the benchmarks (and Google Benchmark) is off by default. It must be enabled using the CMake option `-DLIBCXX_INCLUDE_BENCHMARKS=ON`. When this option is enabled the tests under `libcxx/benchmarks`  can be built using the `libcxx-benchmarks` target.<br>
<br>
On Linux platforms where libstdc++ is the default STL the CMake option `-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON` can be used to build each benchmark test against libstdc++ as well. This is useful for comparing performance between standard libraries.<br>
<br>
Support for benchmarks is currently very minimal. They must be manually run by the user and there is no mechanism for detecting performance regressions.<br>
<br>
Known Issues:<br>
<br>
* `-DLIBCXX_INCLUDE_BENCHMARKS=ON` is only supported for Clang, and not GCC, since the `-stdlib=libc++` option is needed to build Google Benchmark.<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
Reviewers: danalbert, dberlin, chandlerc, mclow.lists, jroelofs<br>
<br>
Subscribers: chandlerc, dberlin, tberghammer, danalbert, srhines, hfinkel<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D22240" rel="noreferrer" target="_blank">https://reviews.llvm.org/D22240</a><br>
<br>
Added:<br>
     libcxx/trunk/benchmarks/CMakeLists.txt<br>
     libcxx/trunk/benchmarks/ContainerBenchmarks.hpp<br>
     libcxx/trunk/benchmarks/GenerateInput.hpp<br>
     libcxx/trunk/benchmarks/algorithms.bench.cpp<br>
     libcxx/trunk/utils/google-benchmark/<br>
     libcxx/trunk/utils/google-benchmark/.gitignore<br>
     libcxx/trunk/utils/google-benchmark/AUTHORS<br>
     libcxx/trunk/utils/google-benchmark/CMakeLists.txt<br>
     libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md<br>
     libcxx/trunk/utils/google-benchmark/CONTRIBUTORS<br>
     libcxx/trunk/utils/google-benchmark/LICENSE<br>
     libcxx/trunk/utils/google-benchmark/README.LLVM<br>
     libcxx/trunk/utils/google-benchmark/README.md<br>
     libcxx/trunk/utils/google-benchmark/cmake/<br>
     libcxx/trunk/utils/google-benchmark/cmake/AddCXXCompilerFlag.cmake<br>
     libcxx/trunk/utils/google-benchmark/cmake/CXXFeatureCheck.cmake<br>
     libcxx/trunk/utils/google-benchmark/cmake/GetGitVersion.cmake<br>
     libcxx/trunk/utils/google-benchmark/cmake/gnu_posix_regex.cpp<br>
     libcxx/trunk/utils/google-benchmark/cmake/posix_regex.cpp<br>
     libcxx/trunk/utils/google-benchmark/cmake/std_regex.cpp<br>
     libcxx/trunk/utils/google-benchmark/cmake/steady_clock.cpp<br>
     libcxx/trunk/utils/google-benchmark/cmake/thread_safety_attributes.cpp<br>
     libcxx/trunk/utils/google-benchmark/include/<br>
     libcxx/trunk/utils/google-benchmark/include/benchmark/<br>
     libcxx/trunk/utils/google-benchmark/include/benchmark/benchmark.h<br>
     libcxx/trunk/utils/google-benchmark/include/benchmark/benchmark_api.h<br>
     libcxx/trunk/utils/google-benchmark/include/benchmark/macros.h<br>
     libcxx/trunk/utils/google-benchmark/include/benchmark/reporter.h<br>
     libcxx/trunk/utils/google-benchmark/mingw.py<br>
     libcxx/trunk/utils/google-benchmark/src/<br>
     libcxx/trunk/utils/google-benchmark/src/CMakeLists.txt<br>
     libcxx/trunk/utils/google-benchmark/src/arraysize.h<br>
     libcxx/trunk/utils/google-benchmark/src/benchmark.cc<br>
     libcxx/trunk/utils/google-benchmark/src/check.h<br>
     libcxx/trunk/utils/google-benchmark/src/colorprint.cc<br>
     libcxx/trunk/utils/google-benchmark/src/colorprint.h<br>
     libcxx/trunk/utils/google-benchmark/src/commandlineflags.cc<br>
     libcxx/trunk/utils/google-benchmark/src/commandlineflags.h<br>
     libcxx/trunk/utils/google-benchmark/src/complexity.cc<br>
     libcxx/trunk/utils/google-benchmark/src/complexity.h<br>
     libcxx/trunk/utils/google-benchmark/src/console_reporter.cc<br>
     libcxx/trunk/utils/google-benchmark/src/csv_reporter.cc<br>
     libcxx/trunk/utils/google-benchmark/src/cycleclock.h<br>
     libcxx/trunk/utils/google-benchmark/src/internal_macros.h<br>
     libcxx/trunk/utils/google-benchmark/src/json_reporter.cc<br>
     libcxx/trunk/utils/google-benchmark/src/log.cc<br>
     libcxx/trunk/utils/google-benchmark/src/log.h<br>
     libcxx/trunk/utils/google-benchmark/src/mutex.h<br>
     libcxx/trunk/utils/google-benchmark/src/re.h<br>
     libcxx/trunk/utils/google-benchmark/src/re_posix.cc<br>
     libcxx/trunk/utils/google-benchmark/src/re_std.cc<br>
     libcxx/trunk/utils/google-benchmark/src/reporter.cc<br>
     libcxx/trunk/utils/google-benchmark/src/sleep.cc<br>
     libcxx/trunk/utils/google-benchmark/src/sleep.h<br>
     libcxx/trunk/utils/google-benchmark/src/stat.h<br>
     libcxx/trunk/utils/google-benchmark/src/string_util.cc<br>
     libcxx/trunk/utils/google-benchmark/src/string_util.h<br>
     libcxx/trunk/utils/google-benchmark/src/sysinfo.cc<br>
     libcxx/trunk/utils/google-benchmark/src/sysinfo.h<br>
     libcxx/trunk/utils/google-benchmark/src/walltime.cc<br>
     libcxx/trunk/utils/google-benchmark/src/walltime.h<br>
     libcxx/trunk/utils/google-benchmark/test/<br>
     libcxx/trunk/utils/google-benchmark/test/CMakeLists.txt<br>
     libcxx/trunk/utils/google-benchmark/test/basic_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/benchmark_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/complexity_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/cxx03_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/diagnostics_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/donotoptimize_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/filter_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/fixture_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/map_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/options_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/reporter_output_test.cc<br>
     libcxx/trunk/utils/google-benchmark/test/skip_with_error_test.cc<br>
Modified:<br>
     libcxx/trunk/CMakeLists.txt<br>
     libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp<br>
     libcxx/trunk/docs/BuildingLibcxx.rst<br>
     libcxx/trunk/docs/TestingLibcxx.rst<br>
<br>
Modified: libcxx/trunk/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=276049&r1=276048&r2=276049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/CMakeLists.txt?rev=276049&r1=276048&r2=276049&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/CMakeLists.txt (original)<br>
+++ libcxx/trunk/CMakeLists.txt Tue Jul 19 18:07:03 2016<br>
@@ -56,6 +56,8 @@ option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRAR<br>
  option(LIBCXX_ENABLE_FILESYSTEM<br>
          "Build filesystem as part of libc++experimental.a" ${LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY})<br>
  option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})<br>
+option(LIBCXX_INCLUDE_BENCHMARKS "Build the libc++ benchmarks and their dependancies" OFF)<br>
+option(LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB "Build the benchmarks against the native STL" OFF)<br>
  option(LIBCXX_INCLUDE_DOCS "Build the libc++ documentation." ${LLVM_INCLUDE_DOCS})<br>
  set(LIBCXX_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING<br>
      "Define suffix of library directory name (32/64)")<br>
@@ -426,6 +428,9 @@ include_directories(include)<br>
  add_subdirectory(include)<br>
  add_subdirectory(lib)<br>
  +if (LIBCXX_INCLUDE_BENCHMARKS)<br>
+  add_subdirectory(benchmarks)<br>
+endif()<br>
  if (LIBCXX_INCLUDE_TESTS)<br>
    add_subdirectory(test)<br>
  endif()<br>
<br>
Added: libcxx/trunk/benchmarks/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/CMakeLists.txt?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/CMakeLists.txt?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/benchmarks/CMakeLists.txt (added)<br>
+++ libcxx/trunk/benchmarks/CMakeLists.txt Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,119 @@<br>
+include(ExternalProject)<br>
+include(CheckCXXCompilerFlag)<br>
+<br>
+#==============================================================================<br>
+# Build Google Benchmark for libc++<br>
+#==============================================================================<br>
+check_cxx_compiler_flag(-stdlib=libc++ LIBCXX_HAS_NO_STDLIB_LIBCXX_FLAG)<br>
+if (NOT LIBCXX_HAS_NO_STDLIB_LIBCXX_FLAG)<br>
+  message(FATAL "Benchmark requires support for the -stdlib=libc++ flag")<br>
+endif()<br>
+<br>
+set(BENCHMARK_LIBCXX_COMPILE_FLAGS<br>
+    -Wno-unused-command-line-argument<br>
+    -nostdinc++<br>
+    -cxx-isystem ${LIBCXX_SOURCE_DIR}/include<br>
+    -stdlib=libc++)<br>
+set(BENCHMARK_LIBCXX_LINK_FLAGS<br>
+    -L${LIBCXX_LIBRARY_DIR}<br>
+    -Wl,-rpath,${LIBCXX_LIBRARY_DIR})<br>
+split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)<br>
+split_list(BENCHMARK_LIBCXX_LINK_FLAGS)<br>
+<br>
+ExternalProject_Add(google-benchmark-libcxx<br>
+        EXCLUDE_FROM_ALL ON<br>
+        DEPENDS cxx<br>
+        PREFIX benchmark-libcxx<br>
+        SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark<br>
+        INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx<br>
+        CMAKE_CACHE_DEFAULT_ARGS<br>
+          -DCMAKE_BUILD_TYPE:STRING=RELEASE<br>
+          -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR><br>
+          -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS}<br>
+          -DCMAKE_SHARED_LINK_FLAGS:STRING=${BENCHMARK_LIBCXX_LINK_FLAGS}<br>
+          -DCMAKE_EXE_LINK_FLAGS:STRING=${BENCHMARK_LIBCXX_LINK_FLAGS}<br>
+          -DBENCHMARK_ENABLE_TESTING:BOOL=OFF)<br>
+<br>
+#==============================================================================<br>
+# Build Google Benchmark for the native stdlib<br>
+#==============================================================================<br>
+if (LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB)<br>
+  ExternalProject_Add(google-benchmark-native<br>
+        EXCLUDE_FROM_ALL ON<br>
+        PREFIX benchmark-native<br>
+        SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark<br>
+        INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native<br>
+        CMAKE_CACHE_ARGS<br>
+          -DBENCHMARK_ENABLE_TESTING:BOOL=OFF<br>
+        CMAKE_CACHE_DEFAULT_ARGS<br>
+          -DCMAKE_BUILD_TYPE:STRING=RELEASE<br>
+          -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>)<br>
+endif()<br>
+<br>
+#==============================================================================<br>
+# Benchmark tests configuration<br>
+#==============================================================================<br>
+add_custom_target(libcxx-benchmarks)<br>
+<br>
+set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx)<br>
+set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native)<br>
+set(BENCHMARK_TEST_COMPILE_FLAGS<br>
+    -std=c++14 -O2<br>
+    -I${BENCHMARK_LIBCXX_INSTALL}/include<br>
+)<br>
+set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS<br>
+    -nostdinc++<br>
+    ${BENCHMARK_TEST_COMPILE_FLAGS}<br>
+    -Wno-user-defined-literals<br>
+)<br>
+set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS<br>
+    -nodefaultlibs<br>
+    -L${BENCHMARK_LIBCXX_INSTALL}/lib/<br>
+)<br>
+set(BENCHMARK_TEST_NATIVE_LINK_FLAGS<br>
+    -L${BENCHMARK_NATIVE_INSTALL}/lib/<br>
+)<br>
+split_list(BENCHMARK_TEST_COMPILE_FLAGS)<br>
+split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS)<br>
+split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS)<br>
+split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS)<br>
+macro(add_benchmark_test name source_file)<br>
+  set(libcxx_target ${name}_libcxx)<br>
+  add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file})<br>
+  add_dependencies(${libcxx_target} cxx google-benchmark-libcxx)<br>
+  add_dependencies(libcxx-benchmarks ${libcxx_target})<br>
+  target_link_libraries(${libcxx_target} cxx -lbenchmark)<br>
+  set_target_properties(${libcxx_target}<br>
+    PROPERTIES<br>
+          OUTPUT_NAME "${name}.libcxx.out"<br>
+          COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}"<br>
+          LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}")<br>
+  if (LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB)<br>
+    set(native_target ${name}_native)<br>
+    add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file})<br>
+    add_dependencies(${native_target} google-benchmark-native)<br>
+    target_link_libraries(${native_target} -lbenchmark)<br>
+    if (LIBCXX_HAS_PTHREAD_LIB)<br>
+      target_link_libraries(${native_target} -pthread)<br>
+    endif()<br>
+    add_dependencies(libcxx-benchmarks ${native_target})<br>
+    set_target_properties(${native_target}<br>
+      PROPERTIES<br>
+          OUTPUT_NAME "${name}.native.out"<br>
+          INCLUDE_DIRECTORIES ""<br>
+          COMPILE_FLAGS "${BENCHMARK_TEST_COMPILE_FLAGS}"<br>
+          LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}")<br>
+  endif()<br>
+endmacro()<br>
+<br>
+<br>
+#==============================================================================<br>
+# Register Benchmark tests<br>
+#==============================================================================<br>
+file(GLOB BENCHMARK_TESTS "*.bench.cpp")<br>
+foreach(test_path ${BENCHMARK_TESTS})<br>
+  get_filename_component(test_file "${test_path}" NAME)<br>
+  message(STATUS "TEST: ${test_file}")<br>
+  string(REPLACE ".bench.cpp" "" test_name "${test_file}")<br>
+  add_benchmark_test(${test_name} ${test_file})<br>
+endforeach()<br>
<br>
Added: libcxx/trunk/benchmarks/ContainerBenchmarks.hpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/ContainerBenchmarks.hpp?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/ContainerBenchmarks.hpp?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/benchmarks/ContainerBenchmarks.hpp (added)<br>
+++ libcxx/trunk/benchmarks/ContainerBenchmarks.hpp Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,69 @@<br>
+#ifndef BENCHMARK_CONTAINER_BENCHMARKS_HPP<br>
+#define BENCHMARK_CONTAINER_BENCHMARKS_HPP<br>
+<br>
+#include <cassert><br>
+<br>
+#include "benchmark/benchmark_api.h"<br>
+<br>
+namespace ContainerBenchmarks {<br>
+<br>
+template <class Container, class GenInputs><br>
+void BM_InsertValue(benchmark::State& st, Container c, GenInputs gen) {<br>
+    auto in = gen(st.range_x());<br>
+    const auto end = in.end();<br>
+    while (st.KeepRunning()) {<br>
+        c.clear();<br>
+        for (auto it = in.begin(); it != end; ++it) {<br>
+            benchmark::DoNotOptimize(&(*c.insert(*it).first));<br>
+        }<br>
+        benchmark::ClobberMemory();<br>
+    }<br>
+}<br>
+<br>
+template <class Container, class GenInputs><br>
+void BM_InsertValueRehash(benchmark::State& st, Container c, GenInputs gen) {<br>
+    auto in = gen(st.range_x());<br>
+    const auto end = in.end();<br>
+    while (st.KeepRunning()) {<br>
+        c.clear();<br>
+        c.rehash(16);<br>
+        for (auto it = in.begin(); it != end; ++it) {<br>
+            benchmark::DoNotOptimize(&(*c.insert(*it).first));<br>
+        }<br>
+        benchmark::ClobberMemory();<br>
+    }<br>
+}<br>
+<br>
+template <class Container, class GenInputs><br>
+static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {<br>
+    auto in = gen(st.range_x());<br>
+    c.insert(in.begin(), in.end());<br>
+    benchmark::DoNotOptimize(&(*c.begin()));<br>
+    const auto end = in.data() + in.size();<br>
+    while (st.KeepRunning()) {<br>
+        for (auto it = in.data(); it != end; ++it) {<br>
+            benchmark::DoNotOptimize(&(*c.find(*it)));<br>
+        }<br>
+        benchmark::ClobberMemory();<br>
+    }<br>
+}<br>
+<br>
+template <class Container, class GenInputs><br>
+static void BM_FindRehash(benchmark::State& st, Container c, GenInputs gen) {<br>
+    c.rehash(8);<br>
+    auto in = gen(st.range_x());<br>
+    c.insert(in.begin(), in.end());<br>
+    benchmark::DoNotOptimize(&(*c.begin()));<br>
+    const auto end = in.data() + in.size();<br>
+    while (st.KeepRunning()) {<br>
+        for (auto it = in.data(); it != end; ++it) {<br>
+            benchmark::DoNotOptimize(&(*c.find(*it)));<br>
+        }<br>
+        benchmark::ClobberMemory();<br>
+    }<br>
+<br>
+}<br>
+<br>
+} // end namespace ContainerBenchmarks<br>
+<br>
+#endif // BENCHMARK_CONTAINER_BENCHMARKS_HPP<br>
<br>
Added: libcxx/trunk/benchmarks/GenerateInput.hpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/GenerateInput.hpp?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/GenerateInput.hpp?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/benchmarks/GenerateInput.hpp (added)<br>
+++ libcxx/trunk/benchmarks/GenerateInput.hpp Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,133 @@<br>
+#ifndef BENCHMARK_GENERATE_INPUT_HPP<br>
+#define BENCHMARK_GENERATE_INPUT_HPP<br>
+<br>
+#include <algorithm><br>
+#include <random><br>
+#include <vector><br>
+#include <string><br>
+#include <climits><br>
+#include <cstddef><br>
+<br>
+static const char Letters[] = {<br>
+    '0','1','2','3','4',<br>
+    '5','6','7','8','9',<br>
+    'A','B','C','D','E','F',<br>
+    'G','H','I','J','K',<br>
+    'L','M','N','O','P',<br>
+    'Q','R','S','T','U',<br>
+    'V','W','X','Y','Z',<br>
+    'a','b','c','d','e','f',<br>
+    'g','h','i','j','k',<br>
+    'l','m','n','o','p',<br>
+    'q','r','s','t','u',<br>
+    'v','w','x','y','z'<br>
+};<br>
+static const std::size_t LettersSize = sizeof(Letters);<br>
+<br>
+inline std::default_random_engine& getRandomEngine() {<br>
+    static std::default_random_engine RandEngine(std::random_device{}());<br>
+    return RandEngine;<br>
+}<br>
+<br>
+inline char getRandomChar() {<br>
+    std::uniform_int_distribution<> LettersDist(0, LettersSize-1);<br>
+    return Letters[LettersDist(getRandomEngine())];<br>
+}<br>
+<br>
+template <class IntT><br>
+inline IntT getRandomInteger() {<br>
+    std::uniform_int_distribution<IntT> dist;<br>
+    return dist(getRandomEngine());<br>
+}<br>
+<br>
+inline std::string getRandomString(std::size_t Len) {<br>
+    std::string str(Len, 0);<br>
+    std::generate_n(str.begin(), Len, &getRandomChar);<br>
+    return str;<br>
+}<br>
+<br>
+template <class IntT><br>
+inline std::vector<IntT> getDuplicateIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs(N, static_cast<IntT>(-1));<br>
+    return inputs;<br>
+}<br>
+<br>
+template <class IntT><br>
+inline std::vector<IntT> getSortedIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs;<br>
+    for (size_t i=0; i < N; i += 1)<br>
+        inputs.push_back(i);<br>
+    return inputs;<br>
+}<br>
+<br>
+template <class IntT><br>
+std::vector<IntT> getSortedLargeIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs;<br>
+    for (size_t i=0; i < N; ++i) {<br>
+        inputs.push_back(i + N);<br>
+    }<br>
+    return inputs;<br>
+}<br>
+<br>
+template <class IntT><br>
+std::vector<IntT> getSortedTopBitsIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs = getSortedIntegerInputs<IntT>(N);<br>
+    for (auto& E : inputs) E <<= ((sizeof(IntT) / 2) * CHAR_BIT);<br>
+    return inputs;<br>
+}<br>
+<br>
+template <class IntT><br>
+inline std::vector<IntT> getReverseSortedIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs;<br>
+    std::size_t i = N;<br>
+    while (i > 0) {<br>
+        --i;<br>
+        inputs.push_back(i);<br>
+    }<br>
+    return inputs;<br>
+}<br>
+<br>
+template <class IntT><br>
+std::vector<IntT> getPipeOrganIntegerInputs(size_t N) {<br>
+    std::vector<IntT> v; v.reserve(N);<br>
+    for (size_t i = 0; i < N/2; ++i) v.push_back(i);<br>
+    for (size_t i = N/2; i < N; ++i) v.push_back(N - i);<br>
+    return v;<br>
+}<br>
+<br>
+<br>
+template <class IntT><br>
+std::vector<IntT> getRandomIntegerInputs(size_t N) {<br>
+    std::vector<IntT> inputs;<br>
+    for (size_t i=0; i < N; ++i) {<br>
+        inputs.push_back(getRandomInteger<IntT>());<br>
+    }<br>
+    return inputs;<br>
+}<br>
+<br>
+inline std::vector<std::string> getDuplicateStringInputs(size_t N) {<br>
+    std::vector<std::string> inputs(N, getRandomString(1024));<br>
+    return inputs;<br>
+}<br>
+<br>
+inline std::vector<std::string> getRandomStringInputs(size_t N) {<br>
+    std::vector<std::string> inputs;<br>
+    for (int i=0; i < N; ++i) {<br>
+        inputs.push_back(getRandomString(1024));<br>
+    }<br>
+    return inputs;<br>
+}<br>
+<br>
+inline std::vector<std::string> getSortedStringInputs(size_t N) {<br>
+    std::vector<std::string> inputs = getRandomStringInputs(N);<br>
+    std::sort(inputs.begin(), inputs.end());<br>
+    return inputs;<br>
+}<br>
+<br>
+inline std::vector<std::string> getReverseSortedStringInputs(size_t N) {<br>
+    std::vector<std::string> inputs = getSortedStringInputs(N);<br>
+    std::reverse(inputs.begin(), inputs.end());<br>
+    return inputs;<br>
+}<br>
+<br>
+#endif // BENCHMARK_GENERATE_INPUT_HPP<br>
<br>
Added: libcxx/trunk/benchmarks/algorithms.bench.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/algorithms.bench.cpp?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/algorithms.bench.cpp?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/benchmarks/algorithms.bench.cpp (added)<br>
+++ libcxx/trunk/benchmarks/algorithms.bench.cpp Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,62 @@<br>
+#include <unordered_set><br>
+#include <vector><br>
+#include <cstdint><br>
+<br>
+#include "benchmark/benchmark_api.h"<br>
+#include "GenerateInput.hpp"<br>
+<br>
+constexpr std::size_t TestNumInputs = 1024;<br>
+<br>
+template <class GenInputs><br>
+void BM_Sort(benchmark::State& st, GenInputs gen) {<br>
+    using ValueType = typename decltype(gen(0))::value_type;<br>
+    const auto in = gen(st.range_x());<br>
+    std::vector<ValueType> inputs[5];<br>
+    auto reset_inputs = [&]() {<br>
+        for (auto& C : inputs) {<br>
+            C = in;<br>
+            benchmark::DoNotOptimize(C.data());<br>
+        }<br>
+    };<br>
+    reset_inputs();<br>
+    while (st.KeepRunning()) {<br>
+        for (auto& I : inputs) {<br>
+            std::sort(I.data(), I.data() + I.size());<br>
+            benchmark::DoNotOptimize(I.data());<br>
+        }<br>
+        st.PauseTiming();<br>
+        reset_inputs();<br>
+        benchmark::ClobberMemory();<br>
+        st.ResumeTiming();<br>
+    }<br>
+}<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, random_uint32,<br>
+    getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_uint32,<br>
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, sorted_descending_uint32,<br>
+    getReverseSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, single_element_uint32,<br>
+    getDuplicateIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, pipe_organ_uint32,<br>
+    getPipeOrganIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, random_strings,<br>
+    getRandomStringInputs)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_strings,<br>
+    getSortedStringInputs)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, sorted_descending_strings,<br>
+    getReverseSortedStringInputs)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Sort, single_element_strings,<br>
+    getDuplicateStringInputs)->Arg(TestNumInputs);<br>
+<br>
+<br>
+BENCHMARK_MAIN()<br>
<br>
Modified: libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp?rev=276049&r1=276048&r2=276049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp?rev=276049&r1=276048&r2=276049&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp (original)<br>
+++ libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp Tue Jul 19 18:07:03 2016<br>
@@ -1,44 +1,268 @@<br>
  #include <unordered_set><br>
  #include <vector><br>
+#include <functional><br>
  #include <cstdint><br>
+#include <cstdlib><br>
+#include <cstring><br>
    #include "benchmark/benchmark_api.h"<br>
  -template <class IntT><br>
-std::vector<IntT> getInputs(size_t N) {<br>
-    std::vector<IntT> inputs;<br>
-    for (size_t i=0; i < N; ++i) {<br>
-        inputs.push_back(i);<br>
-    }<br>
-    return inputs;<br>
+#include "ContainerBenchmarks.hpp"<br>
+#include "GenerateInput.hpp"<br>
+<br>
+using namespace ContainerBenchmarks;<br>
+<br>
+constexpr std::size_t TestNumInputs = 1024;<br>
+<br>
+template <class _Size><br>
+inline __attribute__((__always_inline__))<br>
+_Size loadword(const void* __p) {<br>
+    _Size __r;<br>
+    std::memcpy(&__r, __p, sizeof(__r));<br>
+    return __r;<br>
  }<br>
  -template <class Container, class Inputs><br>
-void BM_SetInsert(benchmark::State& st, Container c, Inputs const& in) {<br>
-    const auto end = in.end();<br>
-    while (st.KeepRunning()) {<br>
-        c.clear();<br>
-        for (auto it = in.begin(); it != end; ++it) {<br>
-            benchmark::DoNotOptimize(c.insert(*it));<br>
-        }<br>
-        benchmark::DoNotOptimize(c);<br>
-    }<br>
+inline __attribute__((__always_inline__))<br>
+std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) {<br>
+    return (__val >> __shift) | (__val << (64 - __shift));<br>
+}<br>
+<br>
+inline __attribute__((__always_inline__))<br>
+std::size_t hash_len_16(std::size_t __u, std::size_t __v) {<br>
+    const  std::size_t __mul = 0x9ddfea08eb382d69ULL;<br>
+    std::size_t __a = (__u ^ __v) * __mul;<br>
+    __a ^= (__a >> 47);<br>
+    std::size_t __b = (__v ^ __a) * __mul;<br>
+    __b ^= (__b >> 47);<br>
+    __b *= __mul;<br>
+    return __b;<br>
+}<br>
+<br>
+<br>
+template <std::size_t _Len><br>
+inline __attribute__((__always_inline__))<br>
+std::size_t hash_len_0_to_8(const char* __s) {<br>
+    static_assert(_Len == 4 || _Len == 8, "");<br>
+    const uint64_t __a = loadword<uint32_t>(__s);<br>
+    const uint64_t __b = loadword<uint32_t>(__s + _Len - 4);<br>
+    return hash_len_16(_Len + (__a << 3), __b);<br>
  }<br>
-BENCHMARK_CAPTURE(BM_SetInsert, uint32_insert,<br>
-    std::unordered_set<uint32_t>{}, getInputs<uint32_t>(1024));<br>
  -template <class Container, class Inputs><br>
-void BM_SetFind(benchmark::State& st, Container c, Inputs const& in) {<br>
-    c.insert(in.begin(), in.end());<br>
-    const auto end = in.end();<br>
+struct UInt32Hash {<br>
+  UInt32Hash() = default;<br>
+  inline __attribute__((__always_inline__))<br>
+  std::size_t operator()(uint32_t data) const {<br>
+      return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));<br>
+  }<br>
+};<br>
+<br>
+struct UInt64Hash {<br>
+  UInt64Hash() = default;<br>
+  inline __attribute__((__always_inline__))<br>
+  std::size_t operator()(uint64_t data) const {<br>
+      return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));<br>
+  }<br>
+};<br>
+<br>
+struct UInt128Hash {<br>
+  UInt128Hash() = default;<br>
+  inline __attribute__((__always_inline__))<br>
+  std::size_t operator()(__uint128_t data) const {<br>
+      const __uint128_t __mask = static_cast<std::size_t>(-1);<br>
+      const std::size_t __a = (std::size_t)(data & __mask);<br>
+      const std::size_t __b = (std::size_t)((data & (__mask << 64)) >> 64);<br>
+      return hash_len_16(__a, rotate_by_at_least_1(__b + 16, 16)) ^ __b;<br>
+  }<br>
+};<br>
+<br>
+struct UInt32Hash2 {<br>
+  UInt32Hash2() = default;<br>
+  inline __attribute__((__always_inline__))<br>
+  std::size_t operator()(uint32_t data) const {<br>
+      const uint32_t __m = 0x5bd1e995;<br>
+      const uint32_t __r = 24;<br>
+      uint32_t __h = 4;<br>
+      uint32_t __k = data;<br>
+        __k *= __m;<br>
+        __k ^= __k >> __r;<br>
+        __k *= __m;<br>
+        __h *= __m;<br>
+        __h ^= __k;<br>
+        __h ^= __h >> 13;<br>
+        __h *= __m;<br>
+        __h ^= __h >> 15;<br>
+    return __h;<br>
+  }<br>
+};<br>
+<br>
+struct UInt64Hash2 {<br>
+  UInt64Hash2() = default;<br>
+  inline __attribute__((__always_inline__))<br>
+  std::size_t operator()(uint64_t data) const {<br>
+      return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));<br>
+  }<br>
+};<br>
+<br>
+//----------------------------------------------------------------------------//<br>
+//                               BM_Hash<br>
+// ---------------------------------------------------------------------------//<br>
+<br>
+template <class HashFn, class GenInputs><br>
+void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {<br>
+    auto in = gen(st.range_x());<br>
+    const auto end = in.data() + in.size();<br>
+    std::size_t last_hash = 0;<br>
+    benchmark::DoNotOptimize(&last_hash);<br>
      while (st.KeepRunning()) {<br>
-        for (auto it = in.begin(); it != end; ++it) {<br>
-            benchmark::DoNotOptimize(c.find(*it));<br>
+        for (auto it = in.data(); it != end; ++it) {<br>
+            benchmark::DoNotOptimize(last_hash += fn(*it));<br>
          }<br>
+        benchmark::ClobberMemory();<br>
      }<br>
  }<br>
-BENCHMARK_CAPTURE(BM_SetFind, uint32_lookup,<br>
-    std::unordered_set<uint32_t>{}, getInputs<uint32_t>(1024));<br>
  +BENCHMARK_CAPTURE(BM_Hash,<br>
+    uint32_random_std_hash,<br>
+    std::hash<uint32_t>{},<br>
+    getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Hash,<br>
+    uint32_random_custom_hash,<br>
+    UInt32Hash{},<br>
+    getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Hash,<br>
+    uint32_top_std_hash,<br>
+    std::hash<uint32_t>{},<br>
+    getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_Hash,<br>
+    uint32_top_custom_hash,<br>
+    UInt32Hash{},<br>
+    getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);<br>
+<br>
+<br>
+//----------------------------------------------------------------------------//<br>
+//                       BM_InsertValue<br>
+// ---------------------------------------------------------------------------//<br>
+<br>
+<br>
+// Sorted Assending //<br>
+BENCHMARK_CAPTURE(BM_InsertValue,<br>
+    unordered_set_uint32,<br>
+    std::unordered_set<uint32_t>{},<br>
+    getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_InsertValue,<br>
+    unordered_set_uint32_sorted,<br>
+    std::unordered_set<uint32_t>{},<br>
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+// Top Bytes //<br>
+BENCHMARK_CAPTURE(BM_InsertValue,<br>
+    unordered_set_top_bits_uint32,<br>
+    std::unordered_set<uint32_t>{},<br>
+    getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_InsertValueRehash,<br>
+    unordered_set_top_bits_uint32,<br>
+    std::unordered_set<uint32_t, UInt32Hash>{},<br>
+    getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+// String //<br>
+BENCHMARK_CAPTURE(BM_InsertValue,<br>
+    unordered_set_string,<br>
+    std::unordered_set<std::string>{},<br>
+    getRandomStringInputs)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_InsertValueRehash,<br>
+    unordered_set_string,<br>
+    std::unordered_set<std::string>{},<br>
+    getRandomStringInputs)->Arg(TestNumInputs);<br>
+<br>
+//----------------------------------------------------------------------------//<br>
+//                         BM_Find<br>
+// ---------------------------------------------------------------------------//<br>
+<br>
+// Random //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_random_uint64,<br>
+    std::unordered_set<uint64_t>{},<br>
+    getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_random_uint64,<br>
+    std::unordered_set<uint64_t, UInt64Hash>{},<br>
+    getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+// Sorted //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_sorted_uint64,<br>
+    std::unordered_set<uint64_t>{},<br>
+    getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_sorted_uint64,<br>
+    std::unordered_set<uint64_t, UInt64Hash>{},<br>
+    getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+<br>
+// Sorted //<br>
+#if 1<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_sorted_uint128,<br>
+    std::unordered_set<__uint128_t, UInt128Hash>{},<br>
+    getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_sorted_uint128,<br>
+    std::unordered_set<__uint128_t, UInt128Hash>{},<br>
+    getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);<br>
+#endif<br>
+<br>
+// Sorted //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_sorted_uint32,<br>
+    std::unordered_set<uint32_t>{},<br>
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_sorted_uint32,<br>
+    std::unordered_set<uint32_t, UInt32Hash2>{},<br>
+    getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);<br>
+<br>
+// Sorted Ascending //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_sorted_large_uint64,<br>
+    std::unordered_set<uint64_t>{},<br>
+    getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_sorted_large_uint64,<br>
+    std::unordered_set<uint64_t, UInt64Hash>{},<br>
+    getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+<br>
+// Top Bits //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_top_bits_uint64,<br>
+    std::unordered_set<uint64_t>{},<br>
+    getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_top_bits_uint64,<br>
+    std::unordered_set<uint64_t, UInt64Hash>{},<br>
+    getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);<br>
+<br>
+// String //<br>
+BENCHMARK_CAPTURE(BM_Find,<br>
+    unordered_set_string,<br>
+    std::unordered_set<std::string>{},<br>
+    getRandomStringInputs)->Arg(TestNumInputs);<br>
+<br>
+BENCHMARK_CAPTURE(BM_FindRehash,<br>
+    unordered_set_string,<br>
+    std::unordered_set<std::string>{},<br>
+    getRandomStringInputs)->Arg(TestNumInputs);<br>
    BENCHMARK_MAIN()<br>
<br>
Modified: libcxx/trunk/docs/BuildingLibcxx.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/BuildingLibcxx.rst?rev=276049&r1=276048&r2=276049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/BuildingLibcxx.rst?rev=276049&r1=276048&r2=276049&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/docs/BuildingLibcxx.rst (original)<br>
+++ libcxx/trunk/docs/BuildingLibcxx.rst Tue Jul 19 18:07:03 2016<br>
@@ -227,7 +227,7 @@ ABI Library Specific Options<br>
    libc++abi is the C++ ABI library used.<br>
    -libc++ Feature options<br>
+libc++ Feature Options<br>
  ----------------------<br>
    .. option:: LIBCXX_ENABLE_EXCEPTIONS:BOOL<br>
@@ -242,9 +242,25 @@ libc++ Feature options<br>
      Build libc++ with run time type information.<br>
  +.. option:: LIBCXX_INCLUDE_BENCHMARKS:BOOL<br>
  -libc++ Feature options<br>
-----------------------<br>
+  **Default**: ``OFF``<br>
+<br>
+  Build the libc++ benchmark tests and the Google Benchmark library needed<br>
+  to support them.<br>
+<br>
+.. option:: LIBCXX_BUILD_BENCHMARK_NATIVE_STDLIB:BOOL<br>
+<br>
+  **Default**:: ``OFF``<br>
+<br>
+  Build the libc++ benchmark tests and Google Benchmark library against the<br>
+  native standard library on the platform. On linux this can be used to compare<br>
+  libc++ to libstdc++ by building the benchmark tests against both standard<br>
+  libraries.<br>
+<br>
+<br>
+libc++ ABI Feature Options<br>
+--------------------------<br>
    The following options allow building libc++ for a different ABI version.<br>
  <br>
Modified: libcxx/trunk/docs/TestingLibcxx.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/TestingLibcxx.rst?rev=276049&r1=276048&r2=276049&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/docs/TestingLibcxx.rst?rev=276049&r1=276048&r2=276049&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/docs/TestingLibcxx.rst (original)<br>
+++ libcxx/trunk/docs/TestingLibcxx.rst Tue Jul 19 18:07:03 2016<br>
@@ -198,3 +198,62 @@ Environment Variables<br>
    If ``LIBCXX_COLOR_DIAGNOSTICS`` is defined then the test suite will attempt<br>
    to use color diagnostic outputs from the compiler.<br>
    Also see :option:`color_diagnostics`.<br>
+<br>
+Benchmarks<br>
+==========<br>
+<br>
+Libc++ contains benchmark tests separately from the test of the test suite.<br>
+The benchmarks are written using the `Google Benchmark`_ library, a copy of which<br>
+is stored in the libc++ repository.<br>
+<br>
+For more information about using the Google Benchmark library see the<br>
+`official documentation <<a href="https://github.com/google/benchmark" rel="noreferrer" target="_blank">https://github.com/google/benchmark</a>>`_.<br>
+<br>
+.. _`Google Benchmark`: <a href="https://github.com/google/benchmark" rel="noreferrer" target="_blank">https://github.com/google/benchmark</a><br>
+<br>
+Building Benchmarks<br>
+-------------------<br>
+<br>
+The benchmark tests are not enabled by default. To build the benchmarks<br>
+libc++ must be configured using the CMake option ``-DLIBCXX_INCLUDE_BENCHMARKS=ON``.<br>
+Then the benchmarks can be built using the ``libcxx-benchmarks`` target.<br>
+<br>
+An example build would look like:<br>
+<br>
+.. code-block:: bash<br>
+<br>
+  $ cd build<br>
+  $ cmake [options] -DLIBCXX_INCLUDE_BENCHMARKS=ON <path to libcxx sources><br>
+  $ make libcxx-benchmarks<br>
+<br>
+This will build all of the benchmarks under ``<libcxx-src>/benchmarks`` to be<br>
+built against the just-built libc++. The compiled tests are output into<br>
+``build/benchmarks``.<br>
+<br>
+The benchmarks can also be built against the platforms native standard library<br>
+using the ``-DLIBCXX_BUILD_BENCHMARKS_NATIVE_STDLIB=ON`` CMake option. This<br>
+is useful for comparing the performance of libc++ to other standard libraries.<br>
+The compiled benchmarks are named ``<test>.libcxx.out`` if they test libc++ and<br>
+``<test>.native.out`` otherwise.<br>
+<br>
+Also See:<br>
+<br>
+  * :ref:`Building Libc++ <build instructions>`<br>
+  * :ref:`CMake Options`<br>
+<br>
+Running Benchmarks<br>
+------------------<br>
+<br>
+The benchmarks must be run manually by the user. Currently there is no way<br>
+to run them as part of the build.<br>
+<br>
+For example:<br>
+<br>
+.. code-block:: bash<br>
+<br>
+  $ cd build/benchmarks<br>
+  $ make libcxx-benchmarks<br>
+  $ ./algorithms.libcxx.out # Runs all the benchmarks<br>
+  $ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks<br>
+<br>
+For more information about running benchmarks see `Google Benchmark`_.<br>
<br>
Added: libcxx/trunk/utils/google-benchmark/.gitignore<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/.gitignore?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/.gitignore?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/.gitignore (added)<br>
+++ libcxx/trunk/utils/google-benchmark/.gitignore Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,46 @@<br>
+*.a<br>
+*.so<br>
+*.so.?*<br>
+*.dll<br>
+*.exe<br>
+*.dylib<br>
+*.cmake<br>
+!/cmake/*.cmake<br>
+*~<br>
+*.pyc<br>
+__pycache__<br>
+<br>
+# lcov<br>
+*.lcov<br>
+/lcov<br>
+<br>
+# cmake files.<br>
+/Testing<br>
+CMakeCache.txt<br>
+CMakeFiles/<br>
+cmake_install.cmake<br>
+<br>
+# makefiles.<br>
+Makefile<br>
+<br>
+# in-source build.<br>
+bin/<br>
+lib/<br>
+/test/*_test<br>
+<br>
+# exuberant ctags.<br>
+tags<br>
+<br>
+# YouCompleteMe configuration.<br>
+.ycm_extra_conf.pyc<br>
+<br>
+# ninja generated files.<br>
+.ninja_deps<br>
+.ninja_log<br>
+build.ninja<br>
+install_manifest.txt<br>
+rules.ninja<br>
+<br>
+# out-of-source build top-level folders.<br>
+build/<br>
+_build/<br>
<br>
Added: libcxx/trunk/utils/google-benchmark/AUTHORS<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/AUTHORS?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/AUTHORS?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/AUTHORS (added)<br>
+++ libcxx/trunk/utils/google-benchmark/AUTHORS Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,33 @@<br>
+# This is the official list of benchmark authors for copyright purposes.<br>
+# This file is distinct from the CONTRIBUTORS files.<br>
+# See the latter for an explanation.<br>
+#<br>
+# Names should be added to this file as:<br>
+#      Name or Organization <email address><br>
+# The email address is not required for organizations.<br>
+#<br>
+# Please keep the list sorted.<br>
+<br>
+Albert Pretorius <<a href="mailto:pretoalb@gmail.com" target="_blank">pretoalb@gmail.com</a>><br>
+Arne Beer <<a href="mailto:arne@twobeer.de" target="_blank">arne@twobeer.de</a>><br>
+Christopher Seymour <<a href="mailto:chris.j.seymour@hotmail.com" target="_blank">chris.j.seymour@hotmail.com</a>><br>
+David Coeurjolly <<a href="mailto:david.coeurjolly@liris.cnrs.fr" target="_blank">david.coeurjolly@liris.cnrs.fr</a>><br>
+Dominic Hamon <<a href="mailto:dma@stripysock.com" target="_blank">dma@stripysock.com</a>><br>
+Eugene Zhuk <<a href="mailto:eugene.zhuk@gmail.com" target="_blank">eugene.zhuk@gmail.com</a>><br>
+Evgeny Safronov <<a href="mailto:division494@gmail.com" target="_blank">division494@gmail.com</a>><br>
+Felix Homann <<a href="mailto:linuxaudio@showlabor.de" target="_blank">linuxaudio@showlabor.de</a>><br>
+Google Inc.<br>
+Ismael Jimenez Martinez <<a href="mailto:ismael.jimenez.martinez@gmail.com" target="_blank">ismael.jimenez.martinez@gmail.com</a>><br>
+JianXiong Zhou <<a href="mailto:zhoujianxiong2@gmail.com" target="_blank">zhoujianxiong2@gmail.com</a>><br>
+Jussi Knuuttila <<a href="mailto:jussi.knuuttila@gmail.com" target="_blank">jussi.knuuttila@gmail.com</a>><br>
+Kaito Udagawa <<a href="mailto:umireon@gmail.com" target="_blank">umireon@gmail.com</a>><br>
+Lei Xu <<a href="mailto:eddyxu@gmail.com" target="_blank">eddyxu@gmail.com</a>><br>
+Matt Clarkson <<a href="mailto:mattyclarkson@gmail.com" target="_blank">mattyclarkson@gmail.com</a>><br>
+Oleksandr Sochka <<a href="mailto:sasha.sochka@gmail.com" target="_blank">sasha.sochka@gmail.com</a>><br>
+Paul Redmond <<a href="mailto:paul.redmond@gmail.com" target="_blank">paul.redmond@gmail.com</a>><br>
+Radoslav Yovchev <<a href="mailto:radoslav.tm@gmail.com" target="_blank">radoslav.tm@gmail.com</a>><br>
+Shuo Chen <<a href="mailto:chenshuo@chenshuo.com" target="_blank">chenshuo@chenshuo.com</a>><br>
+Yusuke Suzuki <<a href="mailto:utatane.tea@gmail.com" target="_blank">utatane.tea@gmail.com</a>><br>
+Dirac Research<br>
+Zbigniew Skowron <<a href="mailto:zbychs@gmail.com" target="_blank">zbychs@gmail.com</a>><br>
+Dominik Czarnota <<a href="mailto:dominik.b.czarnota@gmail.com" target="_blank">dominik.b.czarnota@gmail.com</a>><br>
<br>
Added: libcxx/trunk/utils/google-benchmark/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CMakeLists.txt?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CMakeLists.txt?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/CMakeLists.txt (added)<br>
+++ libcxx/trunk/utils/google-benchmark/CMakeLists.txt Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,147 @@<br>
+cmake_minimum_required (VERSION 2.8.11)<br>
+project (benchmark)<br>
+<br>
+foreach(p<br>
+    CMP0054 # CMake 3.1<br>
+    CMP0056 # export EXE_LINKER_FLAGS to try_run<br>
+    )<br>
+  if(POLICY ${p})<br>
+    cmake_policy(SET ${p} NEW)<br>
+  endif()<br>
+endforeach()<br>
+<br>
+option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)<br>
+option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF)<br>
+# Make sure we can import out CMake functions<br>
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")<br>
+<br>
+# Read the git tags to determine the project version<br>
+include(GetGitVersion)<br>
+get_git_version(GIT_VERSION)<br>
+<br>
+# Tell the user what versions we are using<br>
+string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${GIT_VERSION})<br>
+message("-- Version: ${VERSION}")<br>
+<br>
+# The version of the libraries<br>
+set(GENERIC_LIB_VERSION ${VERSION})<br>
+string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION)<br>
+<br>
+# Import our CMake modules<br>
+include(CheckCXXCompilerFlag)<br>
+include(AddCXXCompilerFlag)<br>
+include(CXXFeatureCheck)<br>
+<br>
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")<br>
+  # Turn compiler warnings up to 11<br>
+  string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")<br>
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")<br>
+  add_definitions(-D_CRT_SECURE_NO_WARNINGS)<br>
+<br>
+  # Link time optimisation<br>
+  if (BENCHMARK_ENABLE_LTO)<br>
+    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")<br>
+    set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")<br>
+    set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")<br>
+    set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")<br>
+<br>
+    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL")<br>
+    string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}")<br>
+    set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")<br>
+    string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")<br>
+    set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")<br>
+    string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")<br>
+    set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")<br>
+<br>
+    set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL")<br>
+    set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG")<br>
+    set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG")<br>
+    set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG")<br>
+  endif()<br>
+else()<br>
+  # Try and enable C++11. Don't use C++14 because it doesn't work in some<br>
+  # configurations.<br>
+  add_cxx_compiler_flag(-std=c++11)<br>
+  if (NOT HAVE_CXX_FLAG_STD_CXX11)<br>
+    add_cxx_compiler_flag(-std=c++0x)<br>
+  endif()<br>
+<br>
+  # Turn compiler warnings up to 11<br>
+  add_cxx_compiler_flag(-Wall)<br>
+<br>
+  add_cxx_compiler_flag(-Wextra)<br>
+  add_cxx_compiler_flag(-Wshadow)<br>
+  add_cxx_compiler_flag(-Werror RELEASE)<br>
+  add_cxx_compiler_flag(-Werror RELWITHDEBINFO)<br>
+  add_cxx_compiler_flag(-Werror MINSIZEREL)<br>
+  add_cxx_compiler_flag(-pedantic)<br>
+  add_cxx_compiler_flag(-pedantic-errors)<br>
+  add_cxx_compiler_flag(-Wshorten-64-to-32)<br>
+  add_cxx_compiler_flag(-Wfloat-equal)<br>
+  add_cxx_compiler_flag(-Wzero-as-null-pointer-constant)<br>
+  add_cxx_compiler_flag(-fstrict-aliasing)<br>
+  if (HAVE_CXX_FLAG_FSTRICT_ALIASING)<br>
+    add_cxx_compiler_flag(-Wstrict-aliasing)<br>
+  endif()<br>
+  add_cxx_compiler_flag(-Wthread-safety)<br>
+  if (HAVE_WTHREAD_SAFETY)<br>
+    add_definitions(-DHAVE_WTHREAD_SAFETY)<br>
+    cxx_feature_check(THREAD_SAFETY_ATTRIBUTES)<br>
+  endif()<br>
+<br>
+  # Link time optimisation<br>
+  if (BENCHMARK_ENABLE_LTO)<br>
+    add_cxx_compiler_flag(-flto)<br>
+    if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")<br>
+      find_program(GCC_AR gcc-ar)<br>
+      if (GCC_AR)<br>
+        set(CMAKE_AR ${GCC_AR})<br>
+      endif()<br>
+      find_program(GCC_RANLIB gcc-ranlib)<br>
+      if (GCC_RANLIB)<br>
+        set(CMAKE_RANLIB ${GCC_RANLIB})<br>
+      endif()<br>
+    endif()<br>
+  endif()<br>
+<br>
+  # Coverage build type<br>
+  set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING<br>
+    "Flags used by the C++ compiler during coverage builds."<br>
+    FORCE)<br>
+  set(CMAKE_EXE_LINKER_FLAGS_COVERAGE<br>
+    "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING<br>
+    "Flags used for linking binaries during coverage builds."<br>
+    FORCE)<br>
+  set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE<br>
+    "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING<br>
+    "Flags used by the shared libraries linker during coverage builds."<br>
+    FORCE)<br>
+  mark_as_advanced(<br>
+    CMAKE_CXX_FLAGS_COVERAGE<br>
+    CMAKE_EXE_LINKER_FLAGS_COVERAGE<br>
+    CMAKE_SHARED_LINKER_FLAGS_COVERAGE)<br>
+  set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING<br>
+    "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage."<br>
+    FORCE)<br>
+  add_cxx_compiler_flag(--coverage COVERAGE)<br>
+endif()<br>
+<br>
+# C++ feature checks<br>
+cxx_feature_check(STD_REGEX)<br>
+cxx_feature_check(GNU_POSIX_REGEX)<br>
+cxx_feature_check(POSIX_REGEX)<br>
+cxx_feature_check(STEADY_CLOCK)<br>
+<br>
+# Ensure we have pthreads<br>
+find_package(Threads REQUIRED)<br>
+<br>
+# Set up directories<br>
+include_directories(${PROJECT_SOURCE_DIR}/include)<br>
+<br>
+# Build the targets<br>
+add_subdirectory(src)<br>
+<br>
+if (BENCHMARK_ENABLE_TESTING)<br>
+  enable_testing()<br>
+  add_subdirectory(test)<br>
+endif()<br>
<br>
Added: libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md (added)<br>
+++ libcxx/trunk/utils/google-benchmark/CONTRIBUTING.md Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,58 @@<br>
+# How to contribute #<br>
+<br>
+We'd love to accept your patches and contributions to this project.  There are<br>
+a just a few small guidelines you need to follow.<br>
+<br>
+<br>
+## Contributor License Agreement ##<br>
+<br>
+Contributions to any Google project must be accompanied by a Contributor<br>
+License Agreement.  This is not a copyright **assignment**, it simply gives<br>
+Google permission to use and redistribute your contributions as part of the<br>
+project.<br>
+<br>
+  * If you are an individual writing original source code and you're sure you<br>
+    own the intellectual property, then you'll need to sign an [individual<br>
+    CLA][].<br>
+<br>
+  * If you work for a company that wants to allow you to contribute your work,<br>
+    then you'll need to sign a [corporate CLA][].<br>
+<br>
+You generally only need to submit a CLA once, so if you've already submitted<br>
+one (even if it was for a different project), you probably don't need to do it<br>
+again.<br>
+<br>
+[individual CLA]: <a href="https://developers.google.com/open-source/cla/individual" rel="noreferrer" target="_blank">https://developers.google.com/open-source/cla/individual</a><br>
+[corporate CLA]: <a href="https://developers.google.com/open-source/cla/corporate" rel="noreferrer" target="_blank">https://developers.google.com/open-source/cla/corporate</a><br>
+<br>
+Once your CLA is submitted (or if you already submitted one for<br>
+another Google project), make a commit adding yourself to the<br>
+[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part<br>
+of your first [pull request][].<br>
+<br>
+[AUTHORS]: AUTHORS<br>
+[CONTRIBUTORS]: CONTRIBUTORS<br>
+<br>
+<br>
+## Submitting a patch ##<br>
+<br>
+  1. It's generally best to start by opening a new issue describing the bug or<br>
+     feature you're intending to fix.  Even if you think it's relatively minor,<br>
+     it's helpful to know what people are working on.  Mention in the initial<br>
+     issue that you are planning to work on that bug or feature so that it can<br>
+     be assigned to you.<br>
+<br>
+  1. Follow the normal process of [forking][] the project, and setup a new<br>
+     branch to work in.  It's important that each group of changes be done in<br>
+     separate branches in order to ensure that a pull request only includes the<br>
+     commits related to that bug or feature.<br>
+<br>
+  1. Do your best to have [well-formed commit messages][] for each change.<br>
+     This provides consistency throughout the project, and ensures that commit<br>
+     messages are able to be formatted properly by various git tools.<br>
+<br>
+  1. Finally, push the commits to your fork and submit a [pull request][].<br>
+<br>
+[forking]: <a href="https://help.github.com/articles/fork-a-repo" rel="noreferrer" target="_blank">https://help.github.com/articles/fork-a-repo</a><br>
+[well-formed commit messages]: <a href="http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html" rel="noreferrer" target="_blank">http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html</a><br>
+[pull request]: <a href="https://help.github.com/articles/creating-a-pull-request" rel="noreferrer" target="_blank">https://help.github.com/articles/creating-a-pull-request</a><br>
<br>
Added: libcxx/trunk/utils/google-benchmark/CONTRIBUTORS<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CONTRIBUTORS?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/CONTRIBUTORS?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/CONTRIBUTORS (added)<br>
+++ libcxx/trunk/utils/google-benchmark/CONTRIBUTORS Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,52 @@<br>
+# People who have agreed to one of the CLAs and can contribute patches.<br>
+# The AUTHORS file lists the copyright holders; this file<br>
+# lists people.  For example, Google employees are listed here<br>
+# but not in AUTHORS, because Google holds the copyright.<br>
+#<br>
+# Names should be added to this file only after verifying that<br>
+# the individual or the individual's organization has agreed to<br>
+# the appropriate Contributor License Agreement, found here:<br>
+#<br>
+# <a href="https://developers.google.com/open-source/cla/individual" rel="noreferrer" target="_blank">https://developers.google.com/open-source/cla/individual</a><br>
+# <a href="https://developers.google.com/open-source/cla/corporate" rel="noreferrer" target="_blank">https://developers.google.com/open-source/cla/corporate</a><br>
+#<br>
+# The agreement for individuals can be filled out on the web.<br>
+#<br>
+# When adding J Random Contributor's name to this file,<br>
+# either J's name or J's organization's name should be<br>
+# added to the AUTHORS file, depending on whether the<br>
+# individual or corporate CLA was used.<br>
+#<br>
+# Names should be added to this file as:<br>
+#     Name <email address><br>
+#<br>
+# Please keep the list sorted.<br>
+<br>
+Albert Pretorius <<a href="mailto:pretoalb@gmail.com" target="_blank">pretoalb@gmail.com</a>><br>
+Arne Beer <<a href="mailto:arne@twobeer.de" target="_blank">arne@twobeer.de</a>><br>
+Billy Robert O'Neal III <<a href="mailto:billy.oneal@gmail.com" target="_blank">billy.oneal@gmail.com</a>> <<a href="mailto:bion@microsoft.com" target="_blank">bion@microsoft.com</a>><br>
+Chris Kennelly <<a href="mailto:ckennelly@google.com" target="_blank">ckennelly@google.com</a>> <<a href="mailto:ckennelly@ckennelly.com" target="_blank">ckennelly@ckennelly.com</a>><br>
+Christopher Seymour <<a href="mailto:chris.j.seymour@hotmail.com" target="_blank">chris.j.seymour@hotmail.com</a>><br>
+David Coeurjolly <<a href="mailto:david.coeurjolly@liris.cnrs.fr" target="_blank">david.coeurjolly@liris.cnrs.fr</a>><br>
+Dominic Hamon <<a href="mailto:dma@stripysock.com" target="_blank">dma@stripysock.com</a>><br>
+Eric Fiselier <<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>><br>
+Eugene Zhuk <<a href="mailto:eugene.zhuk@gmail.com" target="_blank">eugene.zhuk@gmail.com</a>><br>
+Evgeny Safronov <<a href="mailto:division494@gmail.com" target="_blank">division494@gmail.com</a>><br>
+Felix Homann <<a href="mailto:linuxaudio@showlabor.de" target="_blank">linuxaudio@showlabor.de</a>><br>
+Ismael Jimenez Martinez <<a href="mailto:ismael.jimenez.martinez@gmail.com" target="_blank">ismael.jimenez.martinez@gmail.com</a>><br>
+JianXiong Zhou <<a href="mailto:zhoujianxiong2@gmail.com" target="_blank">zhoujianxiong2@gmail.com</a>><br>
+Jussi Knuuttila <<a href="mailto:jussi.knuuttila@gmail.com" target="_blank">jussi.knuuttila@gmail.com</a>><br>
+Kaito Udagawa <<a href="mailto:umireon@gmail.com" target="_blank">umireon@gmail.com</a>><br>
+Kai Wolf <<a href="mailto:kai.wolf@gmail.com" target="_blank">kai.wolf@gmail.com</a>><br>
+Lei Xu <<a href="mailto:eddyxu@gmail.com" target="_blank">eddyxu@gmail.com</a>><br>
+Matt Clarkson <<a href="mailto:mattyclarkson@gmail.com" target="_blank">mattyclarkson@gmail.com</a>><br>
+Oleksandr Sochka <<a href="mailto:sasha.sochka@gmail.com" target="_blank">sasha.sochka@gmail.com</a>><br>
+Pascal Leroy <<a href="mailto:phl@google.com" target="_blank">phl@google.com</a>><br>
+Paul Redmond <<a href="mailto:paul.redmond@gmail.com" target="_blank">paul.redmond@gmail.com</a>><br>
+Pierre Phaneuf <<a href="mailto:pphaneuf@google.com" target="_blank">pphaneuf@google.com</a>><br>
+Radoslav Yovchev <<a href="mailto:radoslav.tm@gmail.com" target="_blank">radoslav.tm@gmail.com</a>><br>
+Shuo Chen <<a href="mailto:chenshuo@chenshuo.com" target="_blank">chenshuo@chenshuo.com</a>><br>
+Yusuke Suzuki <<a href="mailto:utatane.tea@gmail.com" target="_blank">utatane.tea@gmail.com</a>><br>
+Tobias UlvgÃ¥rd <<a href="mailto:tobias.ulvgard@dirac.se" target="_blank">tobias.ulvgard@dirac.se</a>><br>
+Zbigniew Skowron <<a href="mailto:zbychs@gmail.com" target="_blank">zbychs@gmail.com</a>><br>
+Dominik Czarnota <<a href="mailto:dominik.b.czarnota@gmail.com" target="_blank">dominik.b.czarnota@gmail.com</a>><br>
<br>
Added: libcxx/trunk/utils/google-benchmark/LICENSE<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/LICENSE?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/LICENSE?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/LICENSE (added)<br>
+++ libcxx/trunk/utils/google-benchmark/LICENSE Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,202 @@<br>
+<br>
+                                 Apache License<br>
+                           Version 2.0, January 2004<br>
+                        <a href="http://www.apache.org/licenses/" rel="noreferrer" target="_blank">http://www.apache.org/licenses/</a><br>
+<br>
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION<br>
+<br>
+   1. Definitions.<br>
+<br>
+      "License" shall mean the terms and conditions for use, reproduction,<br>
+      and distribution as defined by Sections 1 through 9 of this document.<br>
+<br>
+      "Licensor" shall mean the copyright owner or entity authorized by<br>
+      the copyright owner that is granting the License.<br>
+<br>
+      "Legal Entity" shall mean the union of the acting entity and all<br>
+      other entities that control, are controlled by, or are under common<br>
+      control with that entity. For the purposes of this definition,<br>
+      "control" means (i) the power, direct or indirect, to cause the<br>
+      direction or management of such entity, whether by contract or<br>
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the<br>
+      outstanding shares, or (iii) beneficial ownership of such entity.<br>
+<br>
+      "You" (or "Your") shall mean an individual or Legal Entity<br>
+      exercising permissions granted by this License.<br>
+<br>
+      "Source" form shall mean the preferred form for making modifications,<br>
+      including but not limited to software source code, documentation<br>
+      source, and configuration files.<br>
+<br>
+      "Object" form shall mean any form resulting from mechanical<br>
+      transformation or translation of a Source form, including but<br>
+      not limited to compiled object code, generated documentation,<br>
+      and conversions to other media types.<br>
+<br>
+      "Work" shall mean the work of authorship, whether in Source or<br>
+      Object form, made available under the License, as indicated by a<br>
+      copyright notice that is included in or attached to the work<br>
+      (an example is provided in the Appendix below).<br>
+<br>
+      "Derivative Works" shall mean any work, whether in Source or Object<br>
+      form, that is based on (or derived from) the Work and for which the<br>
+      editorial revisions, annotations, elaborations, or other modifications<br>
+      represent, as a whole, an original work of authorship. For the purposes<br>
+      of this License, Derivative Works shall not include works that remain<br>
+      separable from, or merely link (or bind by name) to the interfaces of,<br>
+      the Work and Derivative Works thereof.<br>
+<br>
+      "Contribution" shall mean any work of authorship, including<br>
+      the original version of the Work and any modifications or additions<br>
+      to that Work or Derivative Works thereof, that is intentionally<br>
+      submitted to Licensor for inclusion in the Work by the copyright owner<br>
+      or by an individual or Legal Entity authorized to submit on behalf of<br>
+      the copyright owner. For the purposes of this definition, "submitted"<br>
+      means any form of electronic, verbal, or written communication sent<br>
+      to the Licensor or its representatives, including but not limited to<br>
+      communication on electronic mailing lists, source code control systems,<br>
+      and issue tracking systems that are managed by, or on behalf of, the<br>
+      Licensor for the purpose of discussing and improving the Work, but<br>
+      excluding communication that is conspicuously marked or otherwise<br>
+      designated in writing by the copyright owner as "Not a Contribution."<br>
+<br>
+      "Contributor" shall mean Licensor and any individual or Legal Entity<br>
+      on behalf of whom a Contribution has been received by Licensor and<br>
+      subsequently incorporated within the Work.<br>
+<br>
+   2. Grant of Copyright License. Subject to the terms and conditions of<br>
+      this License, each Contributor hereby grants to You a perpetual,<br>
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable<br>
+      copyright license to reproduce, prepare Derivative Works of,<br>
+      publicly display, publicly perform, sublicense, and distribute the<br>
+      Work and such Derivative Works in Source or Object form.<br>
+<br>
+   3. Grant of Patent License. Subject to the terms and conditions of<br>
+      this License, each Contributor hereby grants to You a perpetual,<br>
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable<br>
+      (except as stated in this section) patent license to make, have made,<br>
+      use, offer to sell, sell, import, and otherwise transfer the Work,<br>
+      where such license applies only to those patent claims licensable<br>
+      by such Contributor that are necessarily infringed by their<br>
+      Contribution(s) alone or by combination of their Contribution(s)<br>
+      with the Work to which such Contribution(s) was submitted. If You<br>
+      institute patent litigation against any entity (including a<br>
+      cross-claim or counterclaim in a lawsuit) alleging that the Work<br>
+      or a Contribution incorporated within the Work constitutes direct<br>
+      or contributory patent infringement, then any patent licenses<br>
+      granted to You under this License for that Work shall terminate<br>
+      as of the date such litigation is filed.<br>
+<br>
+   4. Redistribution. You may reproduce and distribute copies of the<br>
+      Work or Derivative Works thereof in any medium, with or without<br>
+      modifications, and in Source or Object form, provided that You<br>
+      meet the following conditions:<br>
+<br>
+      (a) You must give any other recipients of the Work or<br>
+          Derivative Works a copy of this License; and<br>
+<br>
+      (b) You must cause any modified files to carry prominent notices<br>
+          stating that You changed the files; and<br>
+<br>
+      (c) You must retain, in the Source form of any Derivative Works<br>
+          that You distribute, all copyright, patent, trademark, and<br>
+          attribution notices from the Source form of the Work,<br>
+          excluding those notices that do not pertain to any part of<br>
+          the Derivative Works; and<br>
+<br>
+      (d) If the Work includes a "NOTICE" text file as part of its<br>
+          distribution, then any Derivative Works that You distribute must<br>
+          include a readable copy of the attribution notices contained<br>
+          within such NOTICE file, excluding those notices that do not<br>
+          pertain to any part of the Derivative Works, in at least one<br>
+          of the following places: within a NOTICE text file distributed<br>
+          as part of the Derivative Works; within the Source form or<br>
+          documentation, if provided along with the Derivative Works; or,<br>
+          within a display generated by the Derivative Works, if and<br>
+          wherever such third-party notices normally appear. The contents<br>
+          of the NOTICE file are for informational purposes only and<br>
+          do not modify the License. You may add Your own attribution<br>
+          notices within Derivative Works that You distribute, alongside<br>
+          or as an addendum to the NOTICE text from the Work, provided<br>
+          that such additional attribution notices cannot be construed<br>
+          as modifying the License.<br>
+<br>
+      You may add Your own copyright statement to Your modifications and<br>
+      may provide additional or different license terms and conditions<br>
+      for use, reproduction, or distribution of Your modifications, or<br>
+      for any such Derivative Works as a whole, provided Your use,<br>
+      reproduction, and distribution of the Work otherwise complies with<br>
+      the conditions stated in this License.<br>
+<br>
+   5. Submission of Contributions. Unless You explicitly state otherwise,<br>
+      any Contribution intentionally submitted for inclusion in the Work<br>
+      by You to the Licensor shall be under the terms and conditions of<br>
+      this License, without any additional terms or conditions.<br>
+      Notwithstanding the above, nothing herein shall supersede or modify<br>
+      the terms of any separate license agreement you may have executed<br>
+      with Licensor regarding such Contributions.<br>
+<br>
+   6. Trademarks. This License does not grant permission to use the trade<br>
+      names, trademarks, service marks, or product names of the Licensor,<br>
+      except as required for reasonable and customary use in describing the<br>
+      origin of the Work and reproducing the content of the NOTICE file.<br>
+<br>
+   7. Disclaimer of Warranty. Unless required by applicable law or<br>
+      agreed to in writing, Licensor provides the Work (and each<br>
+      Contributor provides its Contributions) on an "AS IS" BASIS,<br>
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or<br>
+      implied, including, without limitation, any warranties or conditions<br>
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A<br>
+      PARTICULAR PURPOSE. You are solely responsible for determining the<br>
+      appropriateness of using or redistributing the Work and assume any<br>
+      risks associated with Your exercise of permissions under this License.<br>
+<br>
+   8. Limitation of Liability. In no event and under no legal theory,<br>
+      whether in tort (including negligence), contract, or otherwise,<br>
+      unless required by applicable law (such as deliberate and grossly<br>
+      negligent acts) or agreed to in writing, shall any Contributor be<br>
+      liable to You for damages, including any direct, indirect, special,<br>
+      incidental, or consequential damages of any character arising as a<br>
+      result of this License or out of the use or inability to use the<br>
+      Work (including but not limited to damages for loss of goodwill,<br>
+      work stoppage, computer failure or malfunction, or any and all<br>
+      other commercial damages or losses), even if such Contributor<br>
+      has been advised of the possibility of such damages.<br>
+<br>
+   9. Accepting Warranty or Additional Liability. While redistributing<br>
+      the Work or Derivative Works thereof, You may choose to offer,<br>
+      and charge a fee for, acceptance of support, warranty, indemnity,<br>
+      or other liability obligations and/or rights consistent with this<br>
+      License. However, in accepting such obligations, You may act only<br>
+      on Your own behalf and on Your sole responsibility, not on behalf<br>
+      of any other Contributor, and only if You agree to indemnify,<br>
+      defend, and hold each Contributor harmless for any liability<br>
+      incurred by, or claims asserted against, such Contributor by reason<br>
+      of your accepting any such warranty or additional liability.<br>
+<br>
+   END OF TERMS AND CONDITIONS<br>
+<br>
+   APPENDIX: How to apply the Apache License to your work.<br>
+<br>
+      To apply the Apache License to your work, attach the following<br>
+      boilerplate notice, with the fields enclosed by brackets "[]"<br>
+      replaced with your own identifying information. (Don't include<br>
+      the brackets!)  The text should be enclosed in the appropriate<br>
+      comment syntax for the file format. We also recommend that a<br>
+      file or class name and description of purpose be included on the<br>
+      same "printed page" as the copyright notice for easier<br>
+      identification within third-party archives.<br>
+<br>
+   Copyright [yyyy] [name of copyright owner]<br>
+<br>
+   Licensed under the Apache License, Version 2.0 (the "License");<br>
+   you may not use this file except in compliance with the License.<br>
+   You may obtain a copy of the License at<br>
+<br>
+       <a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer" target="_blank">http://www.apache.org/licenses/LICENSE-2.0</a><br>
+<br>
+   Unless required by applicable law or agreed to in writing, software<br>
+   distributed under the License is distributed on an "AS IS" BASIS,<br>
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>
+   See the License for the specific language governing permissions and<br>
+   limitations under the License.<br>
<br>
Added: libcxx/trunk/utils/google-benchmark/README.LLVM<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/README.LLVM?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/README.LLVM?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/README.LLVM (added)<br>
+++ libcxx/trunk/utils/google-benchmark/README.LLVM Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,6 @@<br>
+LLVM notes<br>
+----------<br>
+<br>
+This directory contains the Google Benchmark source code with some unnecessary<br>
+files removed. Note that this directory is under a different license than<br>
+libc++.<br>
<br>
Added: libcxx/trunk/utils/google-benchmark/README.md<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/README.md?rev=276049&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/utils/google-benchmark/README.md?rev=276049&view=auto</a><br>
==============================================================================<br>
--- libcxx/trunk/utils/google-benchmark/README.md (added)<br>
+++ libcxx/trunk/utils/google-benchmark/README.md Tue Jul 19 18:07:03 2016<br>
@@ -0,0 +1,510 @@<br>
+# benchmark<br>
+[![Build Status](<a href="https://travis-ci.org/google/benchmark.svg?branch=master)](https://travis-ci.org/google/benchmark" rel="noreferrer" target="_blank">https://travis-ci.org/google/benchmark.svg?branch=master)](https://travis-ci.org/google/benchmark</a>)<br>
+[![Build status](<a href="https://ci.appveyor.com/api/projects/status/u0qsyp7t1tk7cpxs/branch/master?svg=true)](https://ci.appveyor.com/project/google/benchmark/branch/master" rel="noreferrer" target="_blank">https://ci.appveyor.com/api/projects/status/u0qsyp7t1tk7cpxs/branch/master?svg=true)](https://ci.appveyor.com/project/google/benchmark/branch/master</a>)<br>
+[![Coverage Status](<a href="https://coveralls.io/repos/google/benchmark/badge.svg)%5D(https://coveralls.io/r/google/benchmark" rel="noreferrer" target="_blank">https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark</a>)<br>
+<br>
+A library to support the benchmarking of functions, similar to unit-tests.<br>
+<br>
+Discussion group: <a href="https://groups.google.com/d/forum/benchmark-discuss" rel="noreferrer" target="_blank">https://groups.google.com/d/forum/benchmark-discuss</a><br>
+<br>
+IRC channel: <a href="https://freenode.net" rel="noreferrer" target="_blank">https://freenode.net</a> #googlebenchmark<br>
+<br>
+## Example usage<br>
+### Basic usage<br>
+Define a function that executes the code to be measured.<br>
+<br>
+```c++<br>
+static void BM_StringCreation(benchmark::State& state) {<br>
+  while (state.KeepRunning())<br>
+    std::string empty_string;<br>
+}<br>
+// Register the function as a benchmark<br>
+BENCHMARK(BM_StringCreation);<br>
+<br>
+// Define another benchmark<br>
+static void BM_StringCopy(benchmark::State& state) {<br>
+  std::string x = "hello";<br>
+  while (state.KeepRunning())<br>
+    std::string copy(x);<br>
+}<br>
+BENCHMARK(BM_StringCopy);<br>
+<br>
+BENCHMARK_MAIN();<br>
+```<br>
+<br>
+### Passing arguments<br>
+Sometimes a family of benchmarks can be implemented with just one routine that<br>
+takes an extra argument to specify which one of the family of benchmarks to<br>
+run. For example, the following code defines a family of benchmarks for<br>
+measuring the speed of `memcpy()` calls of different lengths:<br>
+<br>
+```c++<br>
+static void BM_memcpy(benchmark::State& state) {<br>
+  char* src = new char[state.range_x()];<br>
+  char* dst = new char[state.range_x()];<br>
+  memset(src, 'x', state.range_x());<br>
+  while (state.KeepRunning())<br>
+    memcpy(dst, src, state.range_x());<br>
+  state.SetBytesProcessed(int64_t(state.iterations()) *<br>
+                          int64_t(state.range_x()));<br>
+  delete[] src;<br>
+  delete[] dst;<br>
+}<br>
+BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);<br>
+```<br>
+<br>
+The preceding code is quite repetitive, and can be replaced with the following<br>
+short-hand. The following invocation will pick a few appropriate arguments in<br>
+the specified range and will generate a benchmark for each such argument.<br>
+<br>
+```c++<br>
+BENCHMARK(BM_memcpy)->Range(8, 8<<10);<br>
+```<br>
+<br>
+By default the arguments in the range are generated in multiples of eight and<br>
+the command above selects [ 8, 64, 512, 4k, 8k ]. In the following code the<br>
+range multiplier is changed to multiples of two.<br>
+<br>
+```c++<br>
+BENCHMARK(BM_memcpy)->RangeMultiplier(2)->Range(8, 8<<10);<br>
+```<br>
+Now arguments generated are [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ].<br>
+<br>
+You might have a benchmark that depends on two inputs. For example, the<br>
+following code defines a family of benchmarks for measuring the speed of set<br>
+insertion.<br>
+<br>
+```c++<br>
+static void BM_SetInsert(benchmark::State& state) {<br>
+  while (state.KeepRunning()) {<br>
+    state.PauseTiming();<br>
+    std::set<int> data = ConstructRandomSet(state.range_x());<br>
+    state.ResumeTiming();<br>
+    for (int j = 0; j < state.range_y(); ++j)<br>
+      data.insert(RandomNumber());<br>
+  }<br>
+}<br>
+BENCHMARK(BM_SetInsert)<br>
+    ->ArgPair(1<<10, 1)<br>
+    ->ArgPair(1<<10, 8)<br>
+    ->ArgPair(1<<10, 64)<br>
+    ->ArgPair(1<<10, 512)<br>
+    ->ArgPair(8<<10, 1)<br>
+    ->ArgPair(8<<10, 8)<br>
+    ->ArgPair(8<<10, 64)<br>
+    ->ArgPair(8<<10, 512);<br>
+```<br>
+<br>
+The preceding code is quite repetitive, and can be replaced with the following<br>
+short-hand. The following macro will pick a few appropriate arguments in the<br>
+product of the two specified ranges and will generate a benchmark for each such<br>
+pair.<br>
+<br>
+```c++<br>
+BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512);<br>
+```<br>
+<br>
+For more complex patterns of inputs, passing a custom function to `Apply` allows<br>
+programmatic specification of an arbitrary set of arguments on which to run the<br>
+benchmark. The following example enumerates a dense range on one parameter,<br>
+and a sparse range on the second.<br>
+<br>
+```c++<br>
+static void CustomArguments(benchmark::internal::Benchmark* b) {<br>
+  for (int i = 0; i <= 10; ++i)<br>
+    for (int j = 32; j <= 1024*1024; j *= 8)<br>
+      b->ArgPair(i, j);<br>
+}<br>
+BENCHMARK(BM_SetInsert)->Apply(CustomArguments);<br>
+```<br>
+<br>
+### Calculate asymptotic complexity (Big O)<br>
+Asymptotic complexity might be calculated for a family of benchmarks. The<br>
+following code will calculate the coefficient for the high-order term in the<br>
+running time and the normalized root-mean square error of string comparison.<br>
+<br>
+```c++<br>
+static void BM_StringCompare(benchmark::State& state) {<br>
+  std::string s1(state.range_x(), '-');<br>
+  std::string s2(state.range_x(), '-');<br>
+  while (state.KeepRunning()) {<br>
+    benchmark::DoNotOptimize(s1.compare(s2));<br>
+  }<br>
+  state.SetComplexityN(state.range_x());<br>
+}<br>
+BENCHMARK(BM_StringCompare)<br>
+    ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(benchmark::oN);<br>
+```<br>
+<br>
+As shown in the following invocation, asymptotic complexity might also be<br>
+calculated automatically.<br>
+<br>
+```c++<br>
+BENCHMARK(BM_StringCompare)<br>
+    ->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity();<br>
+```<br>
+<br>
+The following code will specify asymptotic complexity with a lambda function,<br>
+that might be used to customize high-order term calculation.<br>
+<br>
+```c++<br>
+BENCHMARK(BM_StringCompare)->RangeMultiplier(2)<br>
+    ->Range(1<<10, 1<<18)->Complexity([](int n)->double{return n; });<br>
+```<br>
+<br>
+### Templated benchmarks<br>
+Templated benchmarks work the same way: This example produces and consumes<br>
+messages of size `sizeof(v)` `range_x` times. It also outputs throughput in the<br>
+absence of multiprogramming.<br>
+<br>
+```c++<br>
+template <class Q> int BM_Sequential(benchmark::State& state) {<br>
+  Q q;<br>
+  typename Q::value_type v;<br>
+  while (state.KeepRunning()) {<br>
+    for (int i = state.range_x(); i--; )<br>
+      q.push(v);<br>
+    for (int e = state.range_x(); e--; )<br>
+      q.Wait(&v);<br>
+  }<br>
+  // actually messages, not bytes:<br>
+  state.SetBytesProcessed(<br>
+      static_cast<int64_t>(state.iterations())*state.range_x());<br>
+}<br>
+BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);<br>
+```<br>
+<br>
+Three macros are provided for adding benchmark templates.<br>
+<br>
+```c++<br>
+#if __cplusplus >= 201103L // C++11 and greater.<br>
+#define BENCHMARK_TEMPLATE(func, ...) // Takes any number of parameters.<br>
+#else // C++ < C++11<br>
+#define BENCHMARK_TEMPLATE(func, arg1)<br>
+#endif<br>
+#define BENCHMARK_TEMPLATE1(func, arg1)<br>
+#define BENCHMARK_TEMPLATE2(func, arg1, arg2)<br>
+```<br>
+<br>
+## Passing arbitrary arguments to a benchmark<br>
+In C++11 it is possible to define a benchmark that takes an arbitrary number<br>
+of extra arguments. The `BENCHMARK_CAPTURE(func, test_case_name, ...args)`</blockquote>
</blockquote></div><br></div>