├── reflection.creator ├── debug.lua ├── release.lua ├── clang.lua ├── src ├── metafast │ ├── measure_compile_time.cpp │ └── metafast_type_traits.hpp ├── metav3 │ ├── metav3fwd.hpp │ ├── type_traits.hpp │ ├── serialization │ │ ├── json.hpp │ │ ├── optimistic_binary.hpp │ │ └── serialization_test.cpp │ ├── measure_compile_time.cpp │ ├── default_types.hpp │ └── metav3_stl_map.hpp ├── util │ ├── forwarding_constructor.hpp │ ├── pp_concat.hpp │ ├── stl_memory_forward.hpp │ ├── reusable_storage.hpp │ ├── shared_ptr.cpp │ ├── copyableMutex.hpp │ ├── pointer.cpp │ ├── view.cpp │ ├── stl_container_forward.hpp │ ├── compressed_buffer.hpp │ ├── memoizingMap.cpp │ ├── algorithm.hpp │ ├── compressed_buffer.cpp │ ├── memoizingMap.hpp │ ├── shared_ptr.hpp │ ├── type_erasure.cpp │ └── string │ │ └── hashed_string.hpp ├── debug │ ├── error_handling.hpp │ ├── profile.hpp │ ├── assert_settings.hpp │ ├── profile.cpp │ ├── asserting_mutex.hpp │ ├── assert.cpp │ ├── assert_settings.cpp │ ├── assert.hpp │ └── asserting_mutex.cpp ├── meta │ ├── serialization │ │ ├── json.hpp │ │ ├── simpleBinary.hpp │ │ ├── boost_serialization_test.cpp │ │ └── new_meta_compile_test.cpp │ ├── typeTraits.cpp │ ├── metafwd.hpp │ ├── defaultTraits.hpp │ ├── defaulttraits.hpp │ ├── metaStlMap.hpp │ └── typeTraits.hpp ├── flatbuffers │ ├── test.idl │ └── flatbuffers_test.cpp ├── os │ ├── memoryManager.hpp │ ├── mmapped_file.hpp │ ├── memoryManager.cpp │ └── mmapped_file.cpp └── protobuf │ ├── load_fast.proto │ └── protobuf_test.cpp ├── gcc.lua ├── address_sanitizer.lua ├── libs ├── benchmark │ ├── cmake │ │ ├── thread_safety_attributes.cpp │ │ ├── steady_clock.cpp │ │ ├── std_regex.cpp │ │ ├── posix_regex.cpp │ │ ├── gnu_posix_regex.cpp │ │ ├── CXXFeatureCheck.cmake │ │ ├── AddCXXCompilerFlag.cmake │ │ └── GetGitVersion.cmake │ ├── src │ │ ├── sysinfo.h │ │ ├── walltime.h │ │ ├── colorprint.h │ │ ├── sleep.h │ │ ├── log.h │ │ ├── log.cc │ │ ├── internal_macros.h │ │ ├── string_util.h │ │ ├── arraysize.h │ │ ├── re_std.cc │ │ ├── CMakeLists.txt │ │ ├── re_posix.cc │ │ ├── check.h │ │ ├── sleep.cc │ │ ├── re.h │ │ ├── commandlineflags.h │ │ ├── reporter.cc │ │ ├── colorprint.cc │ │ ├── csv_reporter.cc │ │ ├── console_reporter.cc │ │ ├── mutex.h │ │ └── json_reporter.cc │ ├── .gitignore │ ├── test │ │ ├── options_test.cc │ │ ├── cxx03_test.cc │ │ ├── fixture_test.cc │ │ ├── filter_test.cc │ │ ├── basic_test.cc │ │ ├── CMakeLists.txt │ │ └── benchmark_test.cc │ ├── include │ │ └── benchmark │ │ │ ├── benchmark.h │ │ │ ├── macros.h │ │ │ └── reporter.h │ ├── AUTHORS │ ├── .travis-setup.sh │ ├── .travis.yml │ ├── CONTRIBUTORS │ ├── appveyor.yml │ ├── CONTRIBUTING.md │ ├── CMakeLists.txt │ └── .ycm_extra_conf.py ├── z4 │ ├── LICENSE │ └── README.md └── gtest │ ├── src │ ├── gtest_main.cc │ ├── gtest-all.cc │ ├── gtest-typed-test.cc │ └── gtest-test-part.cc │ └── gtest │ └── gtest_prod.h ├── .gitignore ├── reflection.config ├── reflection.includes ├── Tuprules.lua └── Tupfile.lua /reflection.creator: -------------------------------------------------------------------------------- 1 | [General] 2 | -------------------------------------------------------------------------------- /debug.lua: -------------------------------------------------------------------------------- 1 | C_CPP_FLAGS += '-O0' 2 | -------------------------------------------------------------------------------- /release.lua: -------------------------------------------------------------------------------- 1 | C_CPP_FLAGS += '-O2' 2 | DEFINES += '-DNDEBUG' 3 | -------------------------------------------------------------------------------- /clang.lua: -------------------------------------------------------------------------------- 1 | CPP_COMPILER = 'clang++-3.6' 2 | C_COMPILER = 'clang-3.6' 3 | -------------------------------------------------------------------------------- /src/metafast/measure_compile_time.cpp: -------------------------------------------------------------------------------- 1 | #include "metafast/metafast.hpp" 2 | -------------------------------------------------------------------------------- /src/metav3/metav3fwd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "metav3/metav3.hpp" 4 | -------------------------------------------------------------------------------- /src/util/forwarding_constructor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct forwarding_constructor {}; 4 | -------------------------------------------------------------------------------- /gcc.lua: -------------------------------------------------------------------------------- 1 | CPP_COMPILER = 'g++-5' 2 | C_COMPILER = 'gcc-5' 3 | WARNING_FLAGS = '-Wno-unused-variable' 4 | -------------------------------------------------------------------------------- /src/util/pp_concat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define PP_CONCAT(a, b) PP_CONCAT2(a, b) 4 | #define PP_CONCAT2(a, b) a ## b 5 | -------------------------------------------------------------------------------- /address_sanitizer.lua: -------------------------------------------------------------------------------- 1 | C_CPP_FLAGS += '-fsanitize=address' 2 | LINK_FLAGS += '-fsanitize=address' 3 | DEFINES += '-DADDRESS_SANITIZER_BUILD' 4 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/thread_safety_attributes.cpp: -------------------------------------------------------------------------------- 1 | #define HAVE_THREAD_SAFETY_ATTRIBUTES 2 | #include "../src/mutex.h" 3 | 4 | int main() {} 5 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/steady_clock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | typedef std::chrono::steady_clock Clock; 5 | Clock::time_point tp = Clock::now(); 6 | ((void)tp); 7 | } 8 | -------------------------------------------------------------------------------- /src/util/stl_memory_forward.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace std 4 | { 5 | template 6 | class shared_ptr; 7 | template 8 | class unique_ptr; 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .tup 2 | build-gcc 3 | build-gcc-debug 4 | build-clang-debug 5 | build-clang 6 | build-address-sanitizer-debug 7 | *.creator.user* 8 | callgrind.out.* 9 | perf.data 10 | perf.data.old 11 | -------------------------------------------------------------------------------- /reflection.config: -------------------------------------------------------------------------------- 1 | // Add predefined macros for your project here. For example: 2 | // #define THE_ANSWER 42 3 | 4 | #define __STDC_LIMIT_MACROS 5 | #define __STDC_CONSTANT_MACROS 6 | #define BOOST_SYSTEM_NO_DEPRECATED 7 | -------------------------------------------------------------------------------- /src/metav3/type_traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace metav3 6 | { 7 | template 8 | struct remove_pointer : std::remove_pointer 9 | { 10 | }; 11 | template 12 | struct remove_pointer> 13 | { 14 | typedef T type; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /src/debug/error_handling.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "debug/assert.hpp" 4 | 5 | #define UNHANDLED_ERROR(description, ...) RAW_ASSERT(false, description, __VA_ARGS__) 6 | #define UNHANDLED_ERROR_THAT_COULD_BE_HANDLED(...) UNHANDLED_ERROR(__VA_ARGS__) 7 | 8 | #define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) 9 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/std_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | const std::string str = "test0159"; 5 | std::regex re; 6 | re = std::regex("^[a-z]+[0-9]+$", 7 | std::regex_constants::extended | std::regex_constants::nosubs); 8 | return std::regex_search(str, re) ? 0 : -1; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /libs/benchmark/src/sysinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_SYSINFO_H_ 2 | #define BENCHMARK_SYSINFO_H_ 3 | 4 | namespace benchmark { 5 | double MyCPUUsage(); 6 | double ChildrenCPUUsage(); 7 | int NumCPUs(); 8 | double CyclesPerSecond(); 9 | bool CpuScalingEnabled(); 10 | } // end namespace benchmark 11 | 12 | #endif // BENCHMARK_SYSINFO_H_ 13 | -------------------------------------------------------------------------------- /src/meta/serialization/json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "meta/metafwd.hpp" 4 | #include 5 | #include "util/view.hpp" 6 | 7 | struct JsonSerializer 8 | { 9 | std::string serialize(meta::ConstMetaReference object) const; 10 | bool deserialize(meta::MetaReference to_fill, StringView json_text) const; 11 | }; 12 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/posix_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::string str = "test0159"; 5 | regex_t re; 6 | int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); 7 | if (ec != 0) { 8 | return ec; 9 | } 10 | return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/gnu_posix_regex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::string str = "test0159"; 5 | regex_t re; 6 | int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB); 7 | if (ec != 0) { 8 | return ec; 9 | } 10 | return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/metav3/serialization/json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "metav3/metav3fwd.hpp" 4 | #include 5 | #include "util/view.hpp" 6 | 7 | struct JsonSerializer 8 | { 9 | std::string serialize(metav3::ConstMetaReference object) const; 10 | bool deserialize(metav3::MetaReference to_fill, StringView json_text) const; 11 | }; 12 | -------------------------------------------------------------------------------- /src/flatbuffers/test.idl: -------------------------------------------------------------------------------- 1 | namespace test_flatbuffers; 2 | 3 | struct Vec4 4 | { 5 | x : float = 0; 6 | y : float = 0; 7 | z : float = 0; 8 | w : float = 0; 9 | } 10 | 11 | table Monster 12 | { 13 | vec : Vec4; 14 | i : int = 0; 15 | f : float = 0; 16 | } 17 | 18 | table Array 19 | { 20 | array : [Monster]; 21 | } 22 | 23 | root_type Array; 24 | 25 | -------------------------------------------------------------------------------- /src/os/memoryManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace mem 7 | { 8 | struct MemoryManager 9 | { 10 | static size_t GetNumAllocations(); 11 | static size_t GetNumFrees(); 12 | static size_t GetTotalBytesAllocated(); 13 | }; 14 | void * AllocAligned(size_t size, size_t alignment); 15 | void FreeAligned(void * ptr); 16 | } 17 | -------------------------------------------------------------------------------- /libs/benchmark/src/walltime.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_WALLTIME_H_ 2 | #define BENCHMARK_WALLTIME_H_ 3 | 4 | #include 5 | 6 | namespace benchmark { 7 | typedef double WallTime; 8 | 9 | namespace walltime { 10 | WallTime Now(); 11 | } // end namespace walltime 12 | 13 | std::string LocalDateTimeString(); 14 | 15 | } // end namespace benchmark 16 | 17 | #endif // BENCHMARK_WALLTIME_H_ 18 | -------------------------------------------------------------------------------- /src/meta/typeTraits.cpp: -------------------------------------------------------------------------------- 1 | #include "typeTraits.hpp" 2 | #include 3 | 4 | static_assert(meta::is_copy_constructible::value, "copy constructible test"); 5 | static_assert(!meta::is_copy_constructible>::value, "copy constructible test"); 6 | static_assert(!meta::is_copy_constructible>>::value, "copy constructible test"); 7 | 8 | -------------------------------------------------------------------------------- /src/meta/metafwd.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace meta 4 | { 5 | 6 | struct MetaReference; 7 | struct ConstMetaReference; 8 | 9 | enum AccessType 10 | { 11 | PASS_BY_REFERENCE, 12 | PASS_BY_VALUE, 13 | GET_BY_REF_SET_BY_VALUE, 14 | }; 15 | 16 | template 17 | struct MetaTraits; 18 | 19 | struct MetaType; 20 | template 21 | const MetaType & GetMetaType(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/protobuf/load_fast.proto: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | message Vec4 4 | { 5 | required float f0 = 1; 6 | required float f1 = 2; 7 | required float f2 = 3; 8 | required float f3 = 4; 9 | } 10 | 11 | message LoadFastTest 12 | { 13 | required Vec4 vec = 1; 14 | required int32 i = 2; 15 | required float f = 3; 16 | } 17 | 18 | message Array 19 | { 20 | repeated LoadFastTest array = 1; 21 | } 22 | -------------------------------------------------------------------------------- /libs/benchmark/src/colorprint.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_COLORPRINT_H_ 2 | #define BENCHMARK_COLORPRINT_H_ 3 | 4 | namespace benchmark { 5 | enum LogColor { 6 | COLOR_DEFAULT, 7 | COLOR_RED, 8 | COLOR_GREEN, 9 | COLOR_YELLOW, 10 | COLOR_BLUE, 11 | COLOR_MAGENTA, 12 | COLOR_CYAN, 13 | COLOR_WHITE 14 | }; 15 | 16 | void ColorPrintf(LogColor color, const char* fmt, ...); 17 | } // end namespace benchmark 18 | 19 | #endif // BENCHMARK_COLORPRINT_H_ 20 | -------------------------------------------------------------------------------- /src/meta/serialization/simpleBinary.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "meta/metafwd.hpp" 5 | #include 6 | 7 | struct BinarySerializer 8 | { 9 | std::string serialize(meta::ConstMetaReference object) const; 10 | bool deserialize(meta::MetaReference object, const std::string & str) const; 11 | }; 12 | void write_binary(meta::ConstMetaReference object, std::ostream & out); 13 | void read_binary(meta::MetaReference object, std::istream & in); 14 | -------------------------------------------------------------------------------- /src/metav3/serialization/optimistic_binary.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "metav3/metav3.hpp" 5 | #include 6 | 7 | struct OptimisticBinarySerializer 8 | { 9 | std::string serialize(metav3::ConstMetaReference object) const; 10 | bool deserialize(metav3::MetaReference object, const std::string & str) const; 11 | }; 12 | void write_optimistic_binary(metav3::ConstMetaReference object, std::ostream & out); 13 | void read_optimistic_binary(metav3::MetaReference object, ArrayView in); 14 | 15 | -------------------------------------------------------------------------------- /libs/benchmark/src/sleep.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_SLEEP_H_ 2 | #define BENCHMARK_SLEEP_H_ 3 | 4 | #include 5 | 6 | namespace benchmark { 7 | const int64_t kNumMillisPerSecond = 1000LL; 8 | const int64_t kNumMicrosPerMilli = 1000LL; 9 | const int64_t kNumMicrosPerSecond = kNumMillisPerSecond * 1000LL; 10 | const int64_t kNumNanosPerMicro = 1000LL; 11 | const int64_t kNumNanosPerSecond = kNumNanosPerMicro * kNumMicrosPerSecond; 12 | 13 | void SleepForMilliseconds(int milliseconds); 14 | void SleepForSeconds(double seconds); 15 | } // end namespace benchmark 16 | 17 | #endif // BENCHMARK_SLEEP_H_ 18 | -------------------------------------------------------------------------------- /src/metav3/measure_compile_time.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | /*#include 5 | #include "debug/assert.hpp" 6 | #include 7 | #include "util/forwarding_constructor.hpp" 8 | #include "util/view.hpp" 9 | #include "util/pointer.hpp" 10 | #include "util/shared_ptr.hpp" 11 | #include "util/type_erasure.hpp" 12 | #include 13 | #include 14 | #include "util/string/hashed_string.hpp" 15 | #include "util/memoizingMap.hpp" 16 | #include 17 | #include "metav3/type_traits.hpp" 18 | #include "os/memoryManager.hpp" 19 | 20 | #include "metav3/default_types.hpp"*/ 21 | 22 | -------------------------------------------------------------------------------- /src/debug/profile.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | struct Measurer 6 | { 7 | Measurer(); 8 | 9 | std::chrono::high_resolution_clock::duration GetDuration() const; 10 | size_t GetNumAllocations() const; 11 | 12 | private: 13 | std::chrono::high_resolution_clock::time_point before; 14 | size_t num_allocations_before; 15 | }; 16 | 17 | struct ScopedMeasurer 18 | { 19 | ScopedMeasurer(const char * name); 20 | ~ScopedMeasurer(); 21 | const char * name; 22 | std::chrono::high_resolution_clock::time_point before; 23 | size_t num_allocations_before; 24 | size_t num_frees_before; 25 | }; 26 | -------------------------------------------------------------------------------- /libs/benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.so 3 | *.so.?* 4 | *.dll 5 | *.exe 6 | *.dylib 7 | *.cmake 8 | !/cmake/*.cmake 9 | *~ 10 | *.pyc 11 | __pycache__ 12 | 13 | # lcov 14 | *.lcov 15 | /lcov 16 | 17 | # cmake files. 18 | /Testing 19 | CMakeCache.txt 20 | CMakeFiles/ 21 | cmake_install.cmake 22 | 23 | # makefiles. 24 | Makefile 25 | 26 | # in-source build. 27 | bin/ 28 | lib/ 29 | /test/*_test 30 | 31 | # exuberant ctags. 32 | tags 33 | 34 | # YouCompleteMe configuration. 35 | .ycm_extra_conf.pyc 36 | 37 | # ninja generated files. 38 | .ninja_deps 39 | .ninja_log 40 | build.ninja 41 | install_manifest.txt 42 | rules.ninja 43 | 44 | # out-of-source build top-level folders. 45 | build/ 46 | _build/ 47 | -------------------------------------------------------------------------------- /reflection.includes: -------------------------------------------------------------------------------- 1 | . 2 | build-gcc 3 | build-clang 4 | build-clang-debug 5 | build-gcc-debug 6 | libs 7 | libs/gtest 8 | libs/benchmark/include 9 | src 10 | src/debug 11 | src/meta 12 | src/debug 13 | src/util 14 | src/meta/serialization 15 | src/os 16 | src/metav3 17 | src/util/string 18 | src/metav3/serialization 19 | src/metafast 20 | src/protobuf 21 | build-clang/src/flatbuffers 22 | /home/malte/workspace/flatbuffers/include 23 | build-clang/src/protobuf 24 | src/flatbuffers 25 | libs/benchmark/cmake 26 | libs/z4 27 | libs/benchmark/include/benchmark 28 | libs/benchmark/src 29 | libs/gtest/src 30 | libs/gtest/gtest 31 | libs/gtest/gtest/internal 32 | libs/benchmark/test 33 | build-clang-static-analysis 34 | -------------------------------------------------------------------------------- /libs/benchmark/src/log.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_LOG_H_ 2 | #define BENCHMARK_LOG_H_ 3 | 4 | #include 5 | 6 | namespace benchmark { 7 | namespace internal { 8 | 9 | int GetLogLevel(); 10 | void SetLogLevel(int level); 11 | 12 | std::ostream& GetNullLogInstance(); 13 | std::ostream& GetErrorLogInstance(); 14 | 15 | inline std::ostream& GetLogInstanceForLevel(int level) { 16 | if (level <= GetLogLevel()) { 17 | return GetErrorLogInstance(); 18 | } 19 | return GetNullLogInstance(); 20 | } 21 | 22 | } // end namespace internal 23 | } // end namespace benchmark 24 | 25 | #define VLOG(x) (::benchmark::internal::GetLogInstanceForLevel(x) \ 26 | << "-- LOG(" << x << "): ") 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/debug/assert_settings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "assert.hpp" 4 | #include 5 | 6 | namespace assert 7 | { 8 | std::function SetAssertCallback(std::function); 9 | const std::function & GetAssertCallback(); 10 | struct ScopedSetAssertCallback 11 | { 12 | ScopedSetAssertCallback(std::function callback) 13 | : old_callback(SetAssertCallback(std::move(callback))) 14 | { 15 | } 16 | ~ScopedSetAssertCallback() 17 | { 18 | SetAssertCallback(std::move(old_callback)); 19 | } 20 | 21 | private: 22 | std::function old_callback; 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /libs/benchmark/test/options_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark_api.h" 2 | 3 | void BM_basic(benchmark::State& state) { 4 | while (state.KeepRunning()) { 5 | } 6 | } 7 | BENCHMARK(BM_basic); 8 | BENCHMARK(BM_basic)->Arg(42); 9 | BENCHMARK(BM_basic)->Range(1, 8); 10 | BENCHMARK(BM_basic)->DenseRange(10, 15); 11 | BENCHMARK(BM_basic)->ArgPair(42, 42); 12 | BENCHMARK(BM_basic)->RangePair(64, 512, 64, 512); 13 | BENCHMARK(BM_basic)->MinTime(0.7); 14 | BENCHMARK(BM_basic)->UseRealTime(); 15 | BENCHMARK(BM_basic)->ThreadRange(2, 4); 16 | BENCHMARK(BM_basic)->ThreadPerCpu(); 17 | 18 | void CustomArgs(benchmark::internal::Benchmark* b) { 19 | for (int i = 0; i < 10; ++i) { 20 | b->Arg(i); 21 | } 22 | } 23 | 24 | BENCHMARK(BM_basic)->Apply(CustomArgs); 25 | 26 | BENCHMARK_MAIN() 27 | -------------------------------------------------------------------------------- /libs/benchmark/test/cxx03_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "benchmark/benchmark.h" 5 | 6 | #if __cplusplus >= 201103L 7 | #error C++11 or greater detected. Should be C++03. 8 | #endif 9 | 10 | void BM_empty(benchmark::State& state) { 11 | while (state.KeepRunning()) { 12 | volatile std::size_t x = state.iterations(); 13 | ((void)x); 14 | } 15 | } 16 | BENCHMARK(BM_empty); 17 | 18 | template 19 | void BM_template2(benchmark::State& state) { 20 | BM_empty(state); 21 | } 22 | BENCHMARK_TEMPLATE2(BM_template2, int, long); 23 | 24 | template 25 | void BM_template1(benchmark::State& state) { 26 | BM_empty(state); 27 | } 28 | BENCHMARK_TEMPLATE(BM_template1, long); 29 | BENCHMARK_TEMPLATE1(BM_template1, int); 30 | 31 | BENCHMARK_MAIN() 32 | -------------------------------------------------------------------------------- /libs/benchmark/src/log.cc: -------------------------------------------------------------------------------- 1 | #include "log.h" 2 | 3 | #include 4 | 5 | namespace benchmark { 6 | namespace internal { 7 | 8 | int& LoggingLevelImp() { 9 | static int level = 0; 10 | return level; 11 | } 12 | 13 | void SetLogLevel(int value) { 14 | LoggingLevelImp() = value; 15 | } 16 | 17 | int GetLogLevel() { 18 | return LoggingLevelImp(); 19 | } 20 | 21 | class NullLogBuffer : public std::streambuf 22 | { 23 | public: 24 | int overflow(int c) { 25 | return c; 26 | } 27 | }; 28 | 29 | std::ostream& GetNullLogInstance() { 30 | static NullLogBuffer log_buff; 31 | static std::ostream null_log(&log_buff); 32 | return null_log; 33 | } 34 | 35 | std::ostream& GetErrorLogInstance() { 36 | return std::clog; 37 | } 38 | 39 | } // end namespace internal 40 | } // end namespace benchmark 41 | -------------------------------------------------------------------------------- /libs/benchmark/include/benchmark/benchmark.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef BENCHMARK_BENCHMARK_H_ 15 | #define BENCHMARK_BENCHMARK_H_ 16 | 17 | #include "macros.h" 18 | #include "benchmark_api.h" 19 | #include "reporter.h" 20 | 21 | #endif // BENCHMARK_BENCHMARK_H_ 22 | -------------------------------------------------------------------------------- /libs/benchmark/test/fixture_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "benchmark/benchmark.h" 3 | 4 | #include 5 | 6 | class MyFixture : public ::benchmark::Fixture 7 | { 8 | public: 9 | void SetUp() { 10 | data = new int(42); 11 | } 12 | 13 | void TearDown() { 14 | assert(data != nullptr); 15 | delete data; 16 | data = nullptr; 17 | } 18 | 19 | ~MyFixture() { 20 | assert(data == nullptr); 21 | } 22 | 23 | int* data; 24 | }; 25 | 26 | 27 | BENCHMARK_F(MyFixture, Foo)(benchmark::State& st) { 28 | assert(data != nullptr); 29 | assert(*data == 42); 30 | while (st.KeepRunning()) { 31 | } 32 | } 33 | 34 | BENCHMARK_DEFINE_F(MyFixture, Bar)(benchmark::State& st) { 35 | while (st.KeepRunning()) { 36 | } 37 | st.SetItemsProcessed(st.range_x()); 38 | } 39 | BENCHMARK_REGISTER_F(MyFixture, Bar)->Arg(42); 40 | 41 | 42 | BENCHMARK_MAIN() 43 | -------------------------------------------------------------------------------- /src/os/mmapped_file.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util/view.hpp" 4 | #include 5 | 6 | struct UnixFile 7 | { 8 | static const int RDONLY; 9 | static const int RDWR; 10 | static const int WRONLY; 11 | 12 | UnixFile(StringView filename, int flags); 13 | UnixFile(StringView filename, int flags, int mode); 14 | ~UnixFile(); 15 | 16 | bool is_valid() const 17 | { 18 | return file_descriptor >= 0; 19 | } 20 | 21 | void evict_from_os_cache(); 22 | 23 | size_t size(); 24 | size_t read(ArrayView bytes); 25 | 26 | int file_descriptor = -1; 27 | }; 28 | 29 | struct MMappedFileRead 30 | { 31 | MMappedFileRead(StringView filename); 32 | ~MMappedFileRead(); 33 | 34 | ArrayView get_bytes() const; 35 | 36 | void close_and_evict_from_os_cache(); 37 | 38 | private: 39 | struct Internals; 40 | std::unique_ptr internals; 41 | }; 42 | -------------------------------------------------------------------------------- /src/metav3/default_types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "metav3/metav3.hpp" 4 | 5 | namespace metav3 6 | { 7 | 8 | template 9 | struct MetaType::MetaTypeConstructor 10 | { 11 | static const MetaType type; 12 | }; 13 | template 14 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterArray(GetMetaType(), Size); 15 | template 16 | struct MetaType::MetaTypeConstructor 17 | { 18 | static const MetaType type; 19 | }; 20 | template 21 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterPointerToStruct(); 22 | template 23 | struct MetaType::MetaTypeConstructor> 24 | { 25 | static const MetaType type; 26 | }; 27 | template 28 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterPointerToStruct>(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/util/reusable_storage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | template 6 | struct ReusableStorage 7 | { 8 | struct Reusable 9 | { 10 | Reusable(T && object, ReusableStorage & owner) 11 | : object(std::move(object)), owner(owner) 12 | { 13 | } 14 | Reusable(Reusable &&) = default; 15 | ~Reusable() 16 | { 17 | object.clear(); 18 | owner.Store(std::move(object)); 19 | } 20 | 21 | T object; 22 | private: 23 | ReusableStorage & owner; 24 | }; 25 | 26 | 27 | void Store(T && object) 28 | { 29 | if (object.capacity()) storage.push_back(std::move(object)); 30 | } 31 | 32 | Reusable GetObject() 33 | { 34 | if (storage.empty()) return Reusable(T(), *this); 35 | else 36 | { 37 | Reusable result(std::move(storage.back()), *this); 38 | storage.pop_back(); 39 | return result; 40 | } 41 | } 42 | 43 | private: 44 | std::vector storage; 45 | }; 46 | -------------------------------------------------------------------------------- /libs/benchmark/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of benchmark authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | # 5 | # Names should be added to this file as: 6 | # Name or Organization 7 | # The email address is not required for organizations. 8 | # 9 | # Please keep the list sorted. 10 | 11 | Arne Beer 12 | Christopher Seymour 13 | David Coeurjolly 14 | Dominic Hamon 15 | Eugene Zhuk 16 | Evgeny Safronov 17 | Felix Homann 18 | Google Inc. 19 | JianXiong Zhou 20 | Kaito Udagawa 21 | Lei Xu 22 | Matt Clarkson 23 | Oleksandr Sochka 24 | Paul Redmond 25 | Shuo Chen 26 | Yusuke Suzuki 27 | Dirac Research 28 | Zbigniew Skowron 29 | -------------------------------------------------------------------------------- /libs/benchmark/.travis-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Before install 4 | 5 | sudo add-apt-repository -y ppa:kalakris/cmake 6 | if [ "$STD" = "c++11" ]; then 7 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 8 | if [ "$CXX" = "clang++" ]; then 9 | wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add - 10 | sudo add-apt-repository -y "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.6 main" 11 | fi 12 | fi 13 | sudo apt-get update -qq 14 | 15 | # Install 16 | sudo apt-get install -qq cmake 17 | if [ "$STD" = "c++11" ] && [ "$CXX" = "g++" ]; then 18 | sudo apt-get install -qq gcc-4.8 g++-4.8 19 | sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90 20 | sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90 21 | elif [ "$CXX" = "clang++" ]; then 22 | sudo apt-get install -qq clang-3.6 23 | sudo update-alternatives --install /usr/local/bin/clang clang /usr/bin/clang-3.6 90 24 | sudo update-alternatives --install /usr/local/bin/clang++ clang++ /usr/bin/clang++-3.6 90 25 | export PATH=/usr/local/bin:$PATH 26 | fi 27 | -------------------------------------------------------------------------------- /libs/benchmark/src/internal_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_INTERNAL_MACROS_H_ 2 | #define BENCHMARK_INTERNAL_MACROS_H_ 3 | 4 | #include "benchmark/macros.h" 5 | 6 | #ifndef __has_feature 7 | # define __has_feature(x) 0 8 | #endif 9 | 10 | #if __has_feature(cxx_attributes) 11 | # define BENCHMARK_NORETURN [[noreturn]] 12 | #elif defined(__GNUC__) 13 | # define BENCHMARK_NORETURN __attribute__((noreturn)) 14 | #else 15 | # define BENCHMARK_NORETURN 16 | #endif 17 | 18 | #if defined(__CYGWIN__) 19 | # define BENCHMARK_OS_CYGWIN 1 20 | #elif defined(_WIN32) 21 | # define BENCHMARK_OS_WINDOWS 1 22 | #elif defined(__APPLE__) 23 | // TODO(ericwf) This doesn't actually check that it is a Mac OSX system. Just 24 | // that it is an apple system. 25 | # define BENCHMARK_OS_MACOSX 1 26 | #elif defined(__FreeBSD__) 27 | # define BENCHMARK_OS_FREEBSD 1 28 | #elif defined(__linux__) 29 | # define BENCHMARK_OS_LINUX 1 30 | #endif 31 | 32 | #if defined(__clang__) 33 | # define COMPILER_CLANG 34 | #elif defined(_MSC_VER) 35 | # define COMPILER_MSVC 36 | #elif defined(__GNUC__) 37 | # define COMPILER_GCC 38 | #endif 39 | 40 | #endif // BENCHMARK_INTERNAL_MACROS_H_ 41 | -------------------------------------------------------------------------------- /libs/benchmark/src/string_util.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_STRING_UTIL_H_ 2 | #define BENCHMARK_STRING_UTIL_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "internal_macros.h" 8 | 9 | namespace benchmark { 10 | 11 | void AppendHumanReadable(int n, std::string* str); 12 | 13 | std::string HumanReadableNumber(double n); 14 | 15 | std::string StringPrintF(const char* format, ...); 16 | 17 | inline std::ostream& 18 | StringCatImp(std::ostream& out) BENCHMARK_NOEXCEPT 19 | { 20 | return out; 21 | } 22 | 23 | template 24 | inline std::ostream& 25 | StringCatImp(std::ostream& out, First&& f, Rest&&... rest) 26 | { 27 | out << std::forward(f); 28 | return StringCatImp(out, std::forward(rest)...); 29 | } 30 | 31 | template 32 | inline std::string StrCat(Args&&... args) 33 | { 34 | std::ostringstream ss; 35 | StringCatImp(ss, std::forward(args)...); 36 | return ss.str(); 37 | } 38 | 39 | void ReplaceAll(std::string* str, const std::string& from, 40 | const std::string& to); 41 | 42 | } // end namespace benchmark 43 | 44 | #endif // BENCHMARK_STRING_UTIL_H_ 45 | -------------------------------------------------------------------------------- /src/util/shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include "util/shared_ptr.hpp" 2 | 3 | static_assert(sizeof(ptr::small_shared_ptr) == sizeof(void *), "expecting the small_shared_ptr to be the size of just one pointer"); 4 | 5 | #ifndef DISABLE_TESTS 6 | #include 7 | 8 | TEST(small_shared_ptr, simple) 9 | { 10 | struct DestructorCounter 11 | { 12 | DestructorCounter(int & count) 13 | : count(count) 14 | { 15 | } 16 | ~DestructorCounter() 17 | { 18 | ++count; 19 | } 20 | int & count; 21 | }; 22 | 23 | int count = 0; 24 | { 25 | ptr::small_shared_ptr a = ptr::make_shared(count); 26 | ptr::small_shared_ptr b = std::move(a); 27 | ptr::small_shared_ptr c; 28 | { 29 | ptr::small_shared_ptr d = b; 30 | c = d; 31 | } 32 | ASSERT_EQ(0, count); 33 | } 34 | ASSERT_EQ(1, count); 35 | } 36 | 37 | TEST(small_shared_ptr, get) 38 | { 39 | ptr::small_shared_ptr a; 40 | ASSERT_FALSE(a.get()); 41 | ASSERT_FALSE(a); 42 | a = ptr::make_shared(1); 43 | ASSERT_TRUE(a.get()); 44 | ASSERT_TRUE(bool(a)); 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /libs/benchmark/src/arraysize.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_ARRAYSIZE_H_ 2 | #define BENCHMARK_ARRAYSIZE_H_ 3 | 4 | #include "internal_macros.h" 5 | 6 | namespace benchmark { 7 | namespace internal { 8 | // The arraysize(arr) macro returns the # of elements in an array arr. 9 | // The expression is a compile-time constant, and therefore can be 10 | // used in defining new arrays, for example. If you use arraysize on 11 | // a pointer by mistake, you will get a compile-time error. 12 | // 13 | 14 | 15 | // This template function declaration is used in defining arraysize. 16 | // Note that the function doesn't need an implementation, as we only 17 | // use its type. 18 | template 19 | char (&ArraySizeHelper(T (&array)[N]))[N]; 20 | 21 | // That gcc wants both of these prototypes seems mysterious. VC, for 22 | // its part, can't decide which to use (another mystery). Matching of 23 | // template overloads: the final frontier. 24 | #ifndef COMPILER_MSVC 25 | template 26 | char (&ArraySizeHelper(const T (&array)[N]))[N]; 27 | #endif 28 | 29 | #define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array))) 30 | 31 | } // end namespace internal 32 | } // end namespace benchmark 33 | 34 | #endif // BENCHMARK_ARRAYSIZE_H_ 35 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/CXXFeatureCheck.cmake: -------------------------------------------------------------------------------- 1 | # - Compile and run code to check for C++ features 2 | # 3 | # This functions compiles a source file under the `cmake` folder 4 | # and adds the corresponding `HAVE_[FILENAME]` flag to the CMake 5 | # environment 6 | # 7 | # cxx_feature_check( []) 8 | # 9 | # - Example 10 | # 11 | # include(CXXFeatureCheck) 12 | # cxx_feature_check(STD_REGEX) 13 | # Requires CMake 2.6+ 14 | 15 | if(__cxx_feature_check) 16 | return() 17 | endif() 18 | set(__cxx_feature_check INCLUDED) 19 | 20 | function(cxx_feature_check FILE) 21 | string(TOLOWER ${FILE} FILE) 22 | string(TOUPPER ${FILE} VAR) 23 | string(TOUPPER "HAVE_${VAR}" FEATURE) 24 | message("-- Performing Test ${FEATURE}") 25 | try_run(RUN_${FEATURE} COMPILE_${FEATURE} 26 | ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp) 27 | if(RUN_${FEATURE} EQUAL 0) 28 | message("-- Performing Test ${FEATURE} -- success") 29 | set(HAVE_${VAR} 1 PARENT_SCOPE) 30 | add_definitions(-DHAVE_${VAR}) 31 | else() 32 | if(NOT COMPILE_${FEATURE}) 33 | message("-- Performing Test ${FEATURE} -- failed to compile") 34 | else() 35 | message("-- Performing Test ${FEATURE} -- compiled but failed to run") 36 | endif() 37 | endif() 38 | endfunction() 39 | 40 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/AddCXXCompilerFlag.cmake: -------------------------------------------------------------------------------- 1 | # - Adds a compiler flag if it is supported by the compiler 2 | # 3 | # This function checks that the supplied compiler flag is supported and then 4 | # adds it to the corresponding compiler flags 5 | # 6 | # add_cxx_compiler_flag( []) 7 | # 8 | # - Example 9 | # 10 | # include(AddCXXCompilerFlag) 11 | # add_cxx_compiler_flag(-Wall) 12 | # add_cxx_compiler_flag(-no-strict-aliasing RELEASE) 13 | # Requires CMake 2.6+ 14 | 15 | if(__add_cxx_compiler_flag) 16 | return() 17 | endif() 18 | set(__add_cxx_compiler_flag INCLUDED) 19 | 20 | include(CheckCXXCompilerFlag) 21 | 22 | function(add_cxx_compiler_flag FLAG) 23 | string(TOUPPER "HAVE_CXX_FLAG_${FLAG}" SANITIZED_FLAG) 24 | string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG}) 25 | string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) 26 | string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG}) 27 | set(CMAKE_REQUIRED_FLAGS "${FLAG}") 28 | check_cxx_compiler_flag("" ${SANITIZED_FLAG}) 29 | if(${SANITIZED_FLAG}) 30 | set(VARIANT ${ARGV1}) 31 | if(ARGV1) 32 | string(TOUPPER "_${VARIANT}" VARIANT) 33 | endif() 34 | set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE) 35 | endif() 36 | endfunction() 37 | 38 | -------------------------------------------------------------------------------- /libs/benchmark/src/re_std.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "re.h" 16 | 17 | namespace benchmark { 18 | 19 | Regex::Regex() : init_(false) { } 20 | 21 | bool Regex::Init(const std::string& spec, std::string* error) { 22 | try { 23 | re_ = std::regex(spec, std::regex_constants::extended); 24 | 25 | init_ = true; 26 | } catch (const std::regex_error& e) { 27 | if (error) { 28 | *error = e.what(); 29 | } 30 | } 31 | return init_; 32 | } 33 | 34 | Regex::~Regex() { } 35 | 36 | bool Regex::Match(const std::string& str) { 37 | if (!init_) { 38 | return false; 39 | } 40 | 41 | return std::regex_search(str, re_); 42 | } 43 | 44 | } // end namespace benchmark 45 | -------------------------------------------------------------------------------- /src/debug/profile.cpp: -------------------------------------------------------------------------------- 1 | #include "profile.hpp" 2 | #include 3 | #include 4 | 5 | Measurer::Measurer() 6 | : before(std::chrono::high_resolution_clock::now()) 7 | , num_allocations_before(mem::MemoryManager::GetNumAllocations()) 8 | { 9 | } 10 | std::chrono::high_resolution_clock::duration Measurer::GetDuration() const 11 | { 12 | return std::chrono::high_resolution_clock::now() - before; 13 | } 14 | size_t Measurer::GetNumAllocations() const 15 | { 16 | return mem::MemoryManager::GetNumAllocations() - num_allocations_before; 17 | } 18 | 19 | ScopedMeasurer::ScopedMeasurer(const char * name) 20 | : name(name) 21 | , before(std::chrono::high_resolution_clock::now()) 22 | , num_allocations_before(mem::MemoryManager::GetNumAllocations()) 23 | , num_frees_before(mem::MemoryManager::GetNumFrees()) 24 | { 25 | } 26 | ScopedMeasurer::~ScopedMeasurer() 27 | { 28 | auto time_spent = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - before); 29 | size_t num_allocations = mem::MemoryManager::GetNumAllocations() - num_allocations_before; 30 | size_t num_frees = mem::MemoryManager::GetNumFrees() - num_frees_before; 31 | std::cout << name << ": " << time_spent.count() << " ms. " << num_allocations << " allocations, " << num_frees << " frees" << std::endl; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/debug/asserting_mutex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "assert.hpp" 4 | #include 5 | #include 6 | 7 | struct AssertingMutex 8 | { 9 | AssertingMutex() 10 | : is_in_use(0) 11 | { 12 | } 13 | 14 | void lock() 15 | { 16 | RAW_ASSERT(++is_in_use == 1); 17 | } 18 | void unlock() 19 | { 20 | RAW_ASSERT(--is_in_use == 0); 21 | } 22 | 23 | private: 24 | std::atomic is_in_use; 25 | }; 26 | 27 | struct AssertingReaderWriterMutex 28 | { 29 | struct Writer 30 | { 31 | Writer() 32 | : counter(0) 33 | { 34 | } 35 | 36 | void lock() 37 | { 38 | RAW_ASSERT(++counter == 1); 39 | } 40 | void unlock() 41 | { 42 | RAW_ASSERT(--counter == 0); 43 | } 44 | 45 | protected: 46 | std::atomic counter; 47 | }; 48 | struct Reader : private Writer 49 | { 50 | friend struct AssertingReaderWriterMutex; 51 | 52 | void lock() 53 | { 54 | RAW_ASSERT(--counter < 0); 55 | } 56 | void unlock() 57 | { 58 | RAW_ASSERT(++counter <= 0); 59 | } 60 | }; 61 | 62 | operator Writer &() 63 | { 64 | return GetWriter(); 65 | } 66 | operator Reader &() 67 | { 68 | return GetReader(); 69 | } 70 | Writer & GetWriter() 71 | { 72 | return reader; 73 | } 74 | Reader & GetReader() 75 | { 76 | return reader; 77 | } 78 | 79 | private: 80 | Reader reader; 81 | }; 82 | -------------------------------------------------------------------------------- /libs/z4/LICENSE: -------------------------------------------------------------------------------- 1 | LZ4 Library 2 | Copyright (c) 2011-2014, Yann Collet 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /src/debug/assert.cpp: -------------------------------------------------------------------------------- 1 | #include "assert.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "assert_settings.hpp" 12 | 13 | namespace assert 14 | { 15 | namespace detail 16 | { 17 | static bool break_on_throw = true; 18 | static void empty_sigtrap_handler(int) 19 | { 20 | } 21 | BreakOnlyIfDebuggerAttached::BreakOnlyIfDebuggerAttached() 22 | : old_signal_handler(signal(SIGTRAP, &empty_sigtrap_handler)) 23 | { 24 | } 25 | BreakOnlyIfDebuggerAttached::~BreakOnlyIfDebuggerAttached() 26 | { 27 | signal(SIGTRAP, old_signal_handler); 28 | } 29 | CLANG_ANALYZER_NORETURN AssertBreakPoint OnAssert(const AssertContext & context) 30 | { 31 | const std::function & assert_callback = GetAssertCallback(); 32 | if (assert_callback) return assert_callback(context); 33 | else return ShouldBreak; 34 | } 35 | } 36 | ScopedSetBreakOnThrow::ScopedSetBreakOnThrow(bool value) 37 | : old_value(detail::break_on_throw) 38 | { 39 | detail::break_on_throw = value; 40 | } 41 | ScopedSetBreakOnThrow::~ScopedSetBreakOnThrow() 42 | { 43 | detail::break_on_throw = old_value; 44 | } 45 | bool ScopedSetBreakOnThrow::break_on_throw() 46 | { 47 | return detail::break_on_throw; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/util/copyableMutex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // mutexes aren't really copyable but I just want my mutex to be default-initialized 6 | // after a copy. so that's what this mutex class does 7 | struct copyable_mutex 8 | { 9 | copyable_mutex() 10 | { 11 | } 12 | copyable_mutex(const copyable_mutex &) 13 | { 14 | } 15 | copyable_mutex(copyable_mutex &&) 16 | { 17 | } 18 | copyable_mutex & operator=(const copyable_mutex &) 19 | { 20 | return *this; 21 | } 22 | copyable_mutex & operator=(copyable_mutex &&) 23 | { 24 | return *this; 25 | } 26 | 27 | void lock() 28 | { 29 | mutex.lock(); 30 | } 31 | bool try_lock() 32 | { 33 | return mutex.try_lock(); 34 | } 35 | void unlock() 36 | { 37 | mutex.unlock(); 38 | } 39 | 40 | private: 41 | std::mutex mutex; 42 | }; 43 | 44 | struct copyable_recursive_mutex 45 | { 46 | copyable_recursive_mutex() 47 | { 48 | } 49 | copyable_recursive_mutex(const copyable_recursive_mutex &) 50 | { 51 | } 52 | copyable_recursive_mutex(copyable_recursive_mutex &&) 53 | { 54 | } 55 | copyable_recursive_mutex & operator=(const copyable_recursive_mutex &) 56 | { 57 | return *this; 58 | } 59 | copyable_recursive_mutex & operator=(copyable_recursive_mutex &&) 60 | { 61 | return *this; 62 | } 63 | 64 | void lock() 65 | { 66 | recursive_mutex.lock(); 67 | } 68 | bool try_lock() 69 | { 70 | return recursive_mutex.try_lock(); 71 | } 72 | void unlock() 73 | { 74 | recursive_mutex.unlock(); 75 | } 76 | 77 | private: 78 | std::recursive_mutex recursive_mutex; 79 | }; 80 | -------------------------------------------------------------------------------- /libs/benchmark/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | # NOTE: The COMPILER variable is unused. It simply makes the display on 4 | # travis-ci.org more readable. 5 | matrix: 6 | include: 7 | - compiler: gcc 8 | env: COMPILER=g++-4.6 STD=c++0x BUILD_TYPE=Coverage 9 | - compiler: gcc 10 | env: COMPILER=g++-4.6 STD=c++0x BUILD_TYPE=Debug 11 | - compiler: gcc 12 | env: COMPILER=g++-4.6 STD=c++0x BUILD_TYPE=Release 13 | - compiler: gcc 14 | env: COMPILER=g++-4.8 STD=c++11 BUILD_TYPE=Debug 15 | - compiler: gcc 16 | env: COMPILER=g++-4.8 STD=c++11 BUILD_TYPE=Release 17 | - compiler: clang 18 | env: COMPILER=clang++-3.6 STD=c++11 BUILD_TYPE=Debug 19 | - compiler: clang 20 | env: COMPILER=clang++-3.6 STD=c++11 BUILD_TYPE=Release 21 | 22 | before_script: 23 | - source .travis-setup.sh 24 | - mkdir build && cd build 25 | 26 | install: 27 | - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then 28 | PATH=~/.local/bin:${PATH}; 29 | pip install --user --upgrade pip; 30 | pip install --user cpp-coveralls; 31 | fi 32 | 33 | script: 34 | - cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_CXX_FLAGS="-std=${STD}" 35 | - make 36 | - make CTEST_OUTPUT_ON_FAILURE=1 test 37 | 38 | after_success: 39 | - if [ "${BUILD_TYPE}" == "Coverage" -a "${TRAVIS_OS_NAME}" == "linux" ]; then 40 | coveralls --include src --include include --gcov-options '\-lp' --root .. --build-root .; 41 | fi 42 | -------------------------------------------------------------------------------- /libs/z4/README.md: -------------------------------------------------------------------------------- 1 | LZ4 - Library Files 2 | ================================ 3 | 4 | The __lib__ directory contains several files, but you don't necessarily need them all. 5 | 6 | To integrate fast LZ4 compression/decompression into your program, you basically just need "**lz4.c**" and "**lz4.h**". 7 | 8 | For more compression at the cost of compression speed (while preserving decompression speed), use **lz4hc** on top of regular lz4. `lz4hc` only provides compression functions. It also needs `lz4` to compile properly. 9 | 10 | If you want to produce files or data streams compatible with `lz4` command line utility, use **lz4frame**. This library encapsulates lz4-compressed blocks into the [official interoperable frame format]. In order to work properly, lz4frame needs lz4 and lz4hc, and also **xxhash**, which provides error detection algorithm. 11 | (_Advanced stuff_ : It's possible to hide xxhash symbols into a local namespace. This is what `liblz4` does, to avoid symbol duplication in case a user program would link to several libraries containing xxhash symbols.) 12 | 13 | A more complex "lz4frame_static.h" is also provided, although its usage is not recommended. It contains definitions which are not guaranteed to remain stable within future versions. Use for static linking ***only***. 14 | 15 | The other files are not source code. There are : 16 | 17 | - LICENSE : contains the BSD license text 18 | - Makefile : script to compile or install lz4 library (static or dynamic) 19 | - liblz4.pc.in : for pkg-config (make install) 20 | 21 | [official interoperable frame format]: ../lz4_Frame_format.md 22 | -------------------------------------------------------------------------------- /src/util/pointer.cpp: -------------------------------------------------------------------------------- 1 | #include "pointer.hpp" 2 | 3 | 4 | #ifndef DISABLE_GTEST 5 | #include 6 | 7 | TEST(copying_ptr, simple) 8 | { 9 | copying_ptr a(forwarding_constructor{}, 5); 10 | copying_ptr b = a; 11 | ASSERT_EQ(*a, *b); 12 | ASSERT_EQ(a, b); 13 | } 14 | 15 | namespace 16 | { 17 | struct clonable 18 | { 19 | clonable(int a) 20 | : a(a) 21 | { 22 | } 23 | 24 | std::unique_ptr clone() const 25 | { 26 | return std::unique_ptr(new clonable(*this)); 27 | } 28 | 29 | int a = 5; 30 | 31 | bool operator==(const clonable & other) const 32 | { 33 | return a == other.a; 34 | } 35 | }; 36 | } 37 | 38 | TEST(cloning_ptr, simple) 39 | { 40 | cloning_ptr a(forwarding_constructor{}, 10); 41 | cloning_ptr b = a; 42 | ASSERT_EQ(*a, *b); 43 | ASSERT_EQ(a, b); 44 | } 45 | 46 | TEST(dunique_ptr, double_delete) 47 | { 48 | struct self_referential 49 | { 50 | self_referential(dunique_ptr & self, int & destructor_count) 51 | : self(self), destructor_count(destructor_count) 52 | { 53 | } 54 | ~self_referential() 55 | { 56 | ++destructor_count; 57 | self.reset(); 58 | } 59 | 60 | private: 61 | dunique_ptr & self; 62 | int & destructor_count; 63 | }; 64 | int destructor_count = 0; 65 | { 66 | dunique_ptr a; 67 | a.reset(new self_referential(a, destructor_count)); 68 | } 69 | ASSERT_EQ(1, destructor_count); 70 | { 71 | dunique_ptr a; 72 | a.reset(new self_referential(a, destructor_count)); 73 | a.reset(); 74 | } 75 | ASSERT_EQ(2, destructor_count); 76 | } 77 | 78 | #endif 79 | 80 | -------------------------------------------------------------------------------- /src/util/view.cpp: -------------------------------------------------------------------------------- 1 | #include "util/view.hpp" 2 | #include 3 | 4 | std::ostream & operator<<(std::ostream & lhs, StringView rhs) 5 | { 6 | std::copy(rhs.begin(), rhs.end(), std::ostreambuf_iterator(lhs)); 7 | return lhs; 8 | } 9 | 10 | #ifndef DISABLE_TESTS 11 | #include 12 | 13 | TEST(range, equal) 14 | { 15 | StringView a = "hello, world"; 16 | ASSERT_EQ(a, a); 17 | ASSERT_EQ("hello, world", a); 18 | ASSERT_NE("hello, world!", a); 19 | ASSERT_NE("hello world", a); 20 | } 21 | 22 | TEST(range, subrange) 23 | { 24 | StringView a = "hello, world"; 25 | ASSERT_EQ("hello", a.subview(0, 5)); 26 | ASSERT_EQ("world", a.subview(7, 5)); 27 | ASSERT_EQ("orld", a.subview(8)); 28 | ASSERT_EQ("orl", a.subview(8, 3)); 29 | } 30 | 31 | TEST(range, startswith) 32 | { 33 | StringView a = "hello, world"; 34 | ASSERT_TRUE(a.startswith("hello")); 35 | ASSERT_FALSE(a.startswith("world")); 36 | ASSERT_FALSE(a.endswith("hello")); 37 | ASSERT_TRUE(a.endswith("world")); 38 | } 39 | 40 | #include 41 | 42 | TEST(range, as_key) 43 | { 44 | std::unordered_map, int> a; 45 | a["hi"] = 5; 46 | a["there"] = 6; 47 | ASSERT_EQ(5, a["hi"]); 48 | ASSERT_EQ(6, a["there"]); 49 | 50 | std::string non_const_first = "first"; 51 | std::string non_const_second = "second"; 52 | std::unordered_map, int> b; 53 | b[non_const_first] = 7; 54 | b[non_const_second] = 8; 55 | ASSERT_EQ(7, b[non_const_first]); 56 | ASSERT_EQ(8, b[non_const_second]); 57 | } 58 | 59 | #endif 60 | 61 | -------------------------------------------------------------------------------- /libs/benchmark/cmake/GetGitVersion.cmake: -------------------------------------------------------------------------------- 1 | # - Returns a version string from Git tags 2 | # 3 | # This function inspects the annotated git tags for the project and returns a string 4 | # into a CMake variable 5 | # 6 | # get_git_version() 7 | # 8 | # - Example 9 | # 10 | # include(GetGitVersion) 11 | # get_git_version(GIT_VERSION) 12 | # 13 | # Requires CMake 2.8.11+ 14 | find_package(Git) 15 | 16 | if(__get_git_version) 17 | return() 18 | endif() 19 | set(__get_git_version INCLUDED) 20 | 21 | function(get_git_version var) 22 | if(GIT_EXECUTABLE) 23 | execute_process(COMMAND ${GIT_EXECUTABLE} describe --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8 24 | RESULT_VARIABLE status 25 | OUTPUT_VARIABLE GIT_VERSION 26 | ERROR_QUIET) 27 | if(${status}) 28 | set(GIT_VERSION "v0.0.0") 29 | else() 30 | string(STRIP ${GIT_VERSION} GIT_VERSION) 31 | string(REGEX REPLACE "-[0-9]+-g" "-" GIT_VERSION ${GIT_VERSION}) 32 | endif() 33 | 34 | # Work out if the repository is dirty 35 | execute_process(COMMAND ${GIT_EXECUTABLE} update-index -q --refresh 36 | OUTPUT_QUIET 37 | ERROR_QUIET) 38 | execute_process(COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD -- 39 | OUTPUT_VARIABLE GIT_DIFF_INDEX 40 | ERROR_QUIET) 41 | string(COMPARE NOTEQUAL "${GIT_DIFF_INDEX}" "" GIT_DIRTY) 42 | if (${GIT_DIRTY}) 43 | set(GIT_VERSION "${GIT_VERSION}-dirty") 44 | endif() 45 | else() 46 | set(GIT_VERSION "v0.0.0") 47 | endif() 48 | 49 | message("-- git Version: ${GIT_VERSION}") 50 | set(${var} ${GIT_VERSION} PARENT_SCOPE) 51 | endfunction() 52 | -------------------------------------------------------------------------------- /src/protobuf/protobuf_test.cpp: -------------------------------------------------------------------------------- 1 | #include "load_fast.pb.h" 2 | #include "os/mmapped_file.hpp" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "debug/assert.hpp" 9 | 10 | #ifndef DISABLE_TESTS 11 | #include 12 | void ProtobufReading(benchmark::State & state) 13 | { 14 | test::Array array; 15 | for (int i = 0; i < 100000; ++i) 16 | { 17 | test::LoadFastTest * test = array.add_array(); 18 | test->mutable_vec()->set_f0(0.0f); 19 | test->mutable_vec()->set_f1(0.0f); 20 | test->mutable_vec()->set_f2(0.0f); 21 | test->mutable_vec()->set_f3(0.0f); 22 | test->set_f(float(i)); 23 | test->set_i(i % 5); 24 | } 25 | StringView tmp_filename = "/tmp/protobuf_test"; 26 | { 27 | UnixFile file(tmp_filename, O_RDWR | O_CREAT, 0644); 28 | array.SerializePartialToFileDescriptor(file.file_descriptor); 29 | } 30 | while (state.KeepRunning()) 31 | { 32 | UnixFile file(tmp_filename, O_RDONLY); 33 | test::Array copy; 34 | copy.ParsePartialFromFileDescriptor(file.file_descriptor); 35 | for (int i = 0; i < 100000; ++i) 36 | { 37 | const test::LoadFastTest & test = copy.array(i); 38 | RAW_ASSERT(0.0f == test.vec().f0()); 39 | RAW_ASSERT(0.0f == test.vec().f1()); 40 | RAW_ASSERT(0.0f == test.vec().f2()); 41 | RAW_ASSERT(0.0f == test.vec().f3()); 42 | RAW_ASSERT(float(i) == test.f()); 43 | RAW_ASSERT(i % 5 == test.i()); 44 | } 45 | file.evict_from_os_cache(); 46 | } 47 | } 48 | //BENCHMARK(ProtobufReading); 49 | #endif 50 | -------------------------------------------------------------------------------- /libs/benchmark/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Allow the source files to find headers in src/ 2 | include_directories(${PROJECT_SOURCE_DIR}/src) 3 | 4 | # Define the source files 5 | set(SOURCE_FILES "benchmark.cc" "colorprint.cc" "commandlineflags.cc" 6 | "console_reporter.cc" "csv_reporter.cc" "json_reporter.cc" 7 | "log.cc" "reporter.cc" "sleep.cc" "string_util.cc" 8 | "sysinfo.cc" "walltime.cc") 9 | # Determine the correct regular expression engine to use 10 | if(HAVE_STD_REGEX) 11 | set(RE_FILES "re_std.cc") 12 | elseif(HAVE_GNU_POSIX_REGEX) 13 | set(RE_FILES "re_posix.cc") 14 | elseif(HAVE_POSIX_REGEX) 15 | set(RE_FILES "re_posix.cc") 16 | else() 17 | message(FATAL_ERROR "Failed to determine the source files for the regular expression backend") 18 | endif() 19 | 20 | add_library(benchmark ${SOURCE_FILES} ${RE_FILES}) 21 | 22 | 23 | set_target_properties(benchmark PROPERTIES 24 | OUTPUT_NAME "benchmark" 25 | VERSION ${GENERIC_LIB_VERSION} 26 | SOVERSION ${GENERIC_LIB_SOVERSION} 27 | ) 28 | 29 | # Link threads. 30 | target_link_libraries(benchmark ${CMAKE_THREAD_LIBS_INIT}) 31 | 32 | # We need extra libraries on Windows 33 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 34 | target_link_libraries(benchmark Shlwapi) 35 | endif() 36 | 37 | # Expose public API 38 | target_include_directories(benchmark PUBLIC ${PROJECT_SOURCE_DIR}/include) 39 | 40 | # Install target (will install the library to specified CMAKE_INSTALL_PREFIX variable) 41 | install( 42 | TARGETS benchmark 43 | ARCHIVE DESTINATION lib 44 | LIBRARY DESTINATION lib 45 | RUNTIME DESTINATION bin 46 | COMPONENT library) 47 | 48 | install( 49 | DIRECTORY "${PROJECT_SOURCE_DIR}/include/benchmark" 50 | DESTINATION include 51 | FILES_MATCHING PATTERN "*.*h") 52 | -------------------------------------------------------------------------------- /src/util/stl_container_forward.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace std 4 | { 5 | template 6 | class allocator; 7 | 8 | template 9 | struct array; 10 | template 11 | class deque; 12 | template 13 | class list; 14 | template 15 | class forward_list; 16 | template 17 | class vector; 18 | 19 | template 20 | class map; 21 | template 22 | class multimap; 23 | template 24 | class multiset; 25 | template 26 | class set; 27 | 28 | template 29 | struct hash; 30 | 31 | template 32 | class unordered_map; 33 | template 34 | class unordered_multimap; 35 | template 36 | class unordered_multiset; 37 | template 38 | class unordered_set; 39 | 40 | template 41 | class stack; 42 | template 43 | class queue; 44 | template 45 | class priority_queue; 46 | 47 | template 48 | class basic_string; 49 | template 50 | struct char_traits; 51 | typedef basic_string, allocator> string; 52 | typedef basic_string, allocator> wstring; 53 | typedef basic_string, allocator> u16string; 54 | typedef basic_string, allocator> u32string; 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Tuprules.lua: -------------------------------------------------------------------------------- 1 | 2 | tup.include(tup.getconfig('COMPILER') .. '.lua') 3 | tup.include(tup.getconfig('VARIANT') .. '.lua') 4 | build_options = tup.getconfig('BUILD_OPTIONS') 5 | if build_options != '' then 6 | tup.include(build_options .. '.lua') 7 | end 8 | 9 | WARNING_FLAGS += '-Werror' 10 | WARNING_FLAGS += '-Wall' 11 | WARNING_FLAGS += '-Wextra' 12 | WARNING_FLAGS += '-Wno-unknown-pragmas' 13 | WARNING_FLAGS += '-Wdeprecated' 14 | WARNING_FLAGS += '-Wno-comment' 15 | 16 | --DEFINES += '-DFINAL' 17 | DEFINES += '-D_GLIBCXX_USE_DEPRECATED=0' 18 | DEFINES += '-DBOOST_NO_AUTO_PTR' 19 | 20 | -- needed for google benchmark library 21 | DEFINES += '-DHAVE_STD_REGEX' 22 | 23 | C_CPP_FLAGS += WARNING_FLAGS 24 | CPP_FLAGS += '-std=c++14' 25 | --CPP_FLAGS += '-fno-exceptions' 26 | CPP_LINKER = CPP_COMPILER 27 | INCLUDE_DIRS += '-I' .. tup.getcwd() .. '/src' 28 | INCLUDE_DIRS += '-I' .. tup.getcwd() .. '/libs/gtest' 29 | INCLUDE_DIRS += '-I' .. tup.getcwd() .. '/libs/benchmark/include' 30 | INCLUDE_DIRS += '-I' .. tup.getcwd() .. '/libs/z4' 31 | INCLUDE_DIRS += '-Isrc/flatbuffers/' 32 | INCLUDE_DIRS += '-Isrc/protobuf/' 33 | INCLUDE_DIRS += '-I/home/malte/workspace/flatbuffers/include' 34 | C_CPP_FLAGS += INCLUDE_DIRS 35 | C_CPP_FLAGS += DEFINES 36 | C_CPP_FLAGS += '-g' 37 | C_FLAGS = C_CPP_FLAGS 38 | CPP_FLAGS += C_CPP_FLAGS 39 | 40 | function compile_cpp(source, inputs) 41 | output = source .. '.o' 42 | inputs += source 43 | tup.definerule{ inputs = inputs, command = CPP_COMPILER .. ' ' .. table.concat(CPP_FLAGS, ' ') .. ' -c ' .. source .. ' -o ' .. output, outputs = {output} } 44 | end 45 | function compile_c(source, inputs) 46 | output = source .. '.o' 47 | inputs += source 48 | tup.definerule{ inputs = inputs, command = C_COMPILER .. ' ' .. table.concat(C_FLAGS, ' ') .. ' -c ' .. source .. ' -o ' .. output, outputs = {output} } 49 | end 50 | -------------------------------------------------------------------------------- /libs/benchmark/src/re_posix.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #if !defined(HAVE_STD_REGEX) 16 | 17 | #include "check.h" 18 | #include "re.h" 19 | 20 | namespace benchmark { 21 | 22 | Regex::Regex() : init_(false) { } 23 | 24 | bool Regex::Init(const std::string& spec, std::string* error) { 25 | int ec = regcomp(&re_, spec.c_str(), REG_EXTENDED | REG_NOSUB); 26 | if (ec != 0) { 27 | if (error) { 28 | size_t needed = regerror(ec, &re_, nullptr, 0); 29 | char* errbuf = new char[needed]; 30 | regerror(ec, &re_, errbuf, needed); 31 | 32 | // regerror returns the number of bytes necessary to null terminate 33 | // the string, so we move that when assigning to error. 34 | CHECK_NE(needed, 0); 35 | error->assign(errbuf, needed - 1); 36 | 37 | delete[] errbuf; 38 | } 39 | 40 | return false; 41 | } 42 | 43 | init_ = true; 44 | return true; 45 | } 46 | 47 | Regex::~Regex() { 48 | if (init_) { 49 | regfree(&re_); 50 | } 51 | } 52 | 53 | bool Regex::Match(const std::string& str) { 54 | if (!init_) { 55 | return false; 56 | } 57 | 58 | return regexec(&re_, str.c_str(), 0, nullptr, 0) == 0; 59 | } 60 | 61 | } // end namespace benchmark 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /libs/benchmark/include/benchmark/macros.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef BENCHMARK_MACROS_H_ 15 | #define BENCHMARK_MACROS_H_ 16 | 17 | #if __cplusplus < 201103L 18 | # define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 19 | TypeName(const TypeName&); \ 20 | TypeName& operator=(const TypeName&) 21 | #else 22 | # define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 23 | TypeName(const TypeName&) = delete; \ 24 | TypeName& operator=(const TypeName&) = delete 25 | #endif 26 | 27 | #if defined(__GNUC__) 28 | # define BENCHMARK_UNUSED __attribute__((unused)) 29 | # define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline)) 30 | # define BENCHMARK_NOEXCEPT noexcept 31 | #elif defined(_MSC_VER) && !defined(__clang__) 32 | # define BENCHMARK_UNUSED 33 | # define BENCHMARK_ALWAYS_INLINE __forceinline 34 | # define BENCHMARK_NOEXCEPT 35 | # define __func__ __FUNCTION__ 36 | #else 37 | # define BENCHMARK_UNUSED 38 | # define BENCHMARK_ALWAYS_INLINE 39 | # define BENCHMARK_NOEXCEPT 40 | #endif 41 | 42 | #if defined(__GNUC__) 43 | # define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y) 44 | #else 45 | # define BENCHMARK_BUILTIN_EXPECT(x, y) x 46 | #endif 47 | 48 | #endif // BENCHMARK_MACROS_H_ 49 | -------------------------------------------------------------------------------- /libs/benchmark/src/check.h: -------------------------------------------------------------------------------- 1 | #ifndef CHECK_H_ 2 | #define CHECK_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "internal_macros.h" 8 | #include "log.h" 9 | 10 | namespace benchmark { 11 | namespace internal { 12 | 13 | // CheckHandler is the class constructed by failing CHECK macros. CheckHandler 14 | // will log information about the failures and abort when it is destructed. 15 | class CheckHandler { 16 | public: 17 | CheckHandler(const char* check, const char* file, const char* func, int line) 18 | : log_(GetErrorLogInstance()) 19 | { 20 | log_ << file << ":" << line << ": " << func << ": Check `" 21 | << check << "' failed. "; 22 | } 23 | 24 | std::ostream& GetLog() { 25 | return log_; 26 | } 27 | 28 | BENCHMARK_NORETURN ~CheckHandler() { 29 | log_ << std::endl; 30 | std::abort(); 31 | } 32 | 33 | CheckHandler & operator=(const CheckHandler&) = delete; 34 | CheckHandler(const CheckHandler&) = delete; 35 | CheckHandler() = delete; 36 | private: 37 | std::ostream& log_; 38 | }; 39 | 40 | } // end namespace internal 41 | } // end namespace benchmark 42 | 43 | // The CHECK macro returns a std::ostream object that can have extra information 44 | // written to it. 45 | #ifndef NDEBUG 46 | # define CHECK(b) (b ? ::benchmark::internal::GetNullLogInstance() \ 47 | : ::benchmark::internal::CheckHandler( \ 48 | #b, __FILE__, __func__, __LINE__).GetLog()) 49 | #else 50 | # define CHECK(b) ::benchmark::internal::GetNullLogInstance() 51 | #endif 52 | 53 | #define CHECK_EQ(a, b) CHECK((a) == (b)) 54 | #define CHECK_NE(a, b) CHECK((a) != (b)) 55 | #define CHECK_GE(a, b) CHECK((a) >= (b)) 56 | #define CHECK_LE(a, b) CHECK((a) <= (b)) 57 | #define CHECK_GT(a, b) CHECK((a) > (b)) 58 | #define CHECK_LT(a, b) CHECK((a) < (b)) 59 | 60 | #endif // CHECK_H_ 61 | -------------------------------------------------------------------------------- /libs/benchmark/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # People who have agreed to one of the CLAs and can contribute patches. 2 | # The AUTHORS file lists the copyright holders; this file 3 | # lists people. For example, Google employees are listed here 4 | # but not in AUTHORS, because Google holds the copyright. 5 | # 6 | # Names should be added to this file only after verifying that 7 | # the individual or the individual's organization has agreed to 8 | # the appropriate Contributor License Agreement, found here: 9 | # 10 | # https://developers.google.com/open-source/cla/individual 11 | # https://developers.google.com/open-source/cla/corporate 12 | # 13 | # The agreement for individuals can be filled out on the web. 14 | # 15 | # When adding J Random Contributor's name to this file, 16 | # either J's name or J's organization's name should be 17 | # added to the AUTHORS file, depending on whether the 18 | # individual or corporate CLA was used. 19 | # 20 | # Names should be added to this file as: 21 | # Name 22 | # 23 | # Please keep the list sorted. 24 | 25 | Arne Beer 26 | Chris Kennelly 27 | Christopher Seymour 28 | David Coeurjolly 29 | Dominic Hamon 30 | Eugene Zhuk 31 | Evgeny Safronov 32 | Felix Homann 33 | JianXiong Zhou 34 | Kaito Udagawa 35 | Lei Xu 36 | Matt Clarkson 37 | Oleksandr Sochka 38 | Pascal Leroy 39 | Paul Redmond 40 | Pierre Phaneuf 41 | Shuo Chen 42 | Yusuke Suzuki 43 | Tobias Ulvgård 44 | Zbigniew Skowron 45 | -------------------------------------------------------------------------------- /src/meta/defaultTraits.hpp: -------------------------------------------------------------------------------- 1 | // this file is included from newMeta.hpp 2 | #pragma once 3 | 4 | #include "meta/meta.hpp" 5 | #include 6 | 7 | namespace meta 8 | { 9 | 10 | #define INSTANTIATE_CHEAP_TRAITS(type)\ 11 | template<>\ 12 | struct MetaTraits\ 13 | {\ 14 | static constexpr const AccessType access_type = PASS_BY_VALUE;\ 15 | } 16 | INSTANTIATE_CHEAP_TRAITS(bool); 17 | INSTANTIATE_CHEAP_TRAITS(char); 18 | INSTANTIATE_CHEAP_TRAITS(int8_t); 19 | INSTANTIATE_CHEAP_TRAITS(uint8_t); 20 | INSTANTIATE_CHEAP_TRAITS(int16_t); 21 | INSTANTIATE_CHEAP_TRAITS(uint16_t); 22 | INSTANTIATE_CHEAP_TRAITS(int32_t); 23 | INSTANTIATE_CHEAP_TRAITS(uint32_t); 24 | INSTANTIATE_CHEAP_TRAITS(int64_t); 25 | INSTANTIATE_CHEAP_TRAITS(uint64_t); 26 | INSTANTIATE_CHEAP_TRAITS(float); 27 | INSTANTIATE_CHEAP_TRAITS(double); 28 | 29 | #undef INSTANTIATE_CHEAP_TRAITS 30 | 31 | template 32 | struct MetaType::MetaTypeConstructor 33 | { 34 | static const MetaType type; 35 | }; 36 | template 37 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterArray(GetMetaType(), Size); 38 | template 39 | struct MetaType::MetaTypeConstructor 40 | { 41 | static const MetaType type; 42 | }; 43 | template 44 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterPointerToStruct(); 45 | template 46 | struct MetaType::MetaTypeConstructor> 47 | { 48 | static const MetaType type; 49 | }; 50 | template 51 | struct MetaTraits> 52 | { 53 | static constexpr const AccessType access_type = GET_BY_REF_SET_BY_VALUE; 54 | }; 55 | template 56 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterPointerToStruct>(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/meta/defaulttraits.hpp: -------------------------------------------------------------------------------- 1 | // this file is included from newMeta.hpp 2 | #pragma once 3 | 4 | #include "newMeta.hpp" 5 | #include 6 | 7 | namespace meta 8 | { 9 | 10 | #define INSTANTIATE_CHEAP_TRAITS(type)\ 11 | template<>\ 12 | struct MetaTraits\ 13 | {\ 14 | static constexpr const AccessType access_type = PASS_BY_VALUE;\ 15 | } 16 | INSTANTIATE_CHEAP_TRAITS(bool); 17 | INSTANTIATE_CHEAP_TRAITS(char); 18 | INSTANTIATE_CHEAP_TRAITS(int8_t); 19 | INSTANTIATE_CHEAP_TRAITS(uint8_t); 20 | INSTANTIATE_CHEAP_TRAITS(int16_t); 21 | INSTANTIATE_CHEAP_TRAITS(uint16_t); 22 | INSTANTIATE_CHEAP_TRAITS(int32_t); 23 | INSTANTIATE_CHEAP_TRAITS(uint32_t); 24 | INSTANTIATE_CHEAP_TRAITS(int64_t); 25 | INSTANTIATE_CHEAP_TRAITS(uint64_t); 26 | INSTANTIATE_CHEAP_TRAITS(float); 27 | INSTANTIATE_CHEAP_TRAITS(double); 28 | 29 | #undef INSTANTIATE_CHEAP_TRAITS 30 | 31 | template 32 | struct MetaType::MetaTypeConstructor 33 | { 34 | static const MetaType type; 35 | }; 36 | template 37 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterArray(GetMetaType(), Size); 38 | template 39 | struct MetaType::MetaTypeConstructor 40 | { 41 | static const MetaType type; 42 | }; 43 | template 44 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterPointerToStruct(); 45 | template 46 | struct MetaType::MetaTypeConstructor> 47 | { 48 | static const MetaType type; 49 | }; 50 | template 51 | struct MetaTraits> 52 | { 53 | static constexpr const AccessType access_type = GET_BY_REF_SET_BY_VALUE; 54 | }; 55 | template 56 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterPointerToStruct>(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /libs/gtest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | std::cout << "Running main() from gtest_main.cc\n"; 36 | 37 | testing::InitGoogleTest(&argc, argv); 38 | return RUN_ALL_TESTS(); 39 | } 40 | -------------------------------------------------------------------------------- /libs/benchmark/src/sleep.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "sleep.h" 16 | 17 | #include 18 | #include 19 | 20 | #include "internal_macros.h" 21 | 22 | #ifdef BENCHMARK_OS_WINDOWS 23 | #include 24 | #endif 25 | 26 | namespace benchmark { 27 | #ifdef BENCHMARK_OS_WINDOWS 28 | // Window's Sleep takes milliseconds argument. 29 | void SleepForMilliseconds(int milliseconds) { Sleep(milliseconds); } 30 | void SleepForSeconds(double seconds) { 31 | SleepForMilliseconds(static_cast(kNumMillisPerSecond * seconds)); 32 | } 33 | #else // BENCHMARK_OS_WINDOWS 34 | void SleepForMicroseconds(int microseconds) { 35 | struct timespec sleep_time; 36 | sleep_time.tv_sec = microseconds / kNumMicrosPerSecond; 37 | sleep_time.tv_nsec = (microseconds % kNumMicrosPerSecond) * kNumNanosPerMicro; 38 | while (nanosleep(&sleep_time, &sleep_time) != 0 && errno == EINTR) 39 | ; // Ignore signals and wait for the full interval to elapse. 40 | } 41 | 42 | void SleepForMilliseconds(int milliseconds) { 43 | SleepForMicroseconds(static_cast(milliseconds) * kNumMicrosPerMilli); 44 | } 45 | 46 | void SleepForSeconds(double seconds) { 47 | SleepForMicroseconds(static_cast(seconds * kNumMicrosPerSecond)); 48 | } 49 | #endif // BENCHMARK_OS_WINDOWS 50 | } // end namespace benchmark 51 | -------------------------------------------------------------------------------- /src/meta/serialization/boost_serialization_test.cpp: -------------------------------------------------------------------------------- 1 | #ifndef DISABLE_GTEST 2 | #include 3 | #include 4 | //#define TEST_BOOST_COMPILE_TIME 5 | #ifdef TEST_BOOST_COMPILE_TIME 6 | #include 7 | #include 8 | 9 | template 10 | struct TestStruct : TestStruct 11 | { 12 | TestStruct(int j = 0) 13 | : TestStruct(j), int_member(i + j), struct_member(j) 14 | { 15 | } 16 | 17 | int int_member; 18 | 19 | TestStruct & GetStructMember() 20 | { 21 | return struct_member; 22 | } 23 | 24 | bool operator==(const TestStruct & other) const 25 | { 26 | return int_member == other.int_member && struct_member == other.struct_member && TestStruct::operator==(other); 27 | } 28 | 29 | template 30 | void serialize(Archive & ar, unsigned) 31 | { 32 | ar & static_cast &>(*this); 33 | ar & int_member; 34 | ar & struct_member; 35 | } 36 | 37 | private: 38 | TestStruct struct_member; 39 | }; 40 | 41 | template<> 42 | struct TestStruct<0> 43 | { 44 | TestStruct(int = 0) 45 | : last_member(0.5f) 46 | { 47 | } 48 | 49 | bool operator==(const TestStruct & other) const 50 | { 51 | return last_member == other.last_member; 52 | } 53 | 54 | template 55 | void serialize(Archive & ar, unsigned) 56 | { 57 | ar & last_member; 58 | } 59 | 60 | float last_member; 61 | }; 62 | 63 | TEST(boost, compile_time) 64 | { 65 | std::stringstream str; 66 | boost::archive::binary_oarchive oa(str); 67 | typedef TestStruct<96> ChosenStruct; 68 | std::unique_ptr original(new ChosenStruct(5)); 69 | oa << *original; 70 | std::unique_ptr copy(new ChosenStruct()); 71 | std::cout << str.str().size() << std::endl; 72 | boost::archive::binary_iarchive ia(str); 73 | ia >> *copy; 74 | ASSERT_EQ(*original, *copy); 75 | } 76 | 77 | #endif 78 | #endif 79 | -------------------------------------------------------------------------------- /src/flatbuffers/flatbuffers_test.cpp: -------------------------------------------------------------------------------- 1 | #include "test_generated.h" 2 | 3 | #include "os/mmapped_file.hpp" 4 | #include "debug/assert.hpp" 5 | 6 | #ifndef DISABLE_TESTS 7 | #include 8 | #include 9 | void FlatbuffersReading(benchmark::State & state) 10 | { 11 | namespace fb = flatbuffers; 12 | namespace tfb = test_flatbuffers; 13 | std::string filename = "/tmp/flatbuffers_test"; 14 | { 15 | fb::FlatBufferBuilder builder; 16 | std::vector> monster_array; 17 | for (int i = 0; i < 100000; ++i) 18 | { 19 | tfb::Vec4 vec(0.0f, 0.0f, 0.0f, 0.0f); 20 | monster_array.push_back(test_flatbuffers::CreateMonster(builder, &vec, i % 5, float(i))); 21 | } 22 | auto vec = builder.CreateVector(monster_array); 23 | tfb::ArrayBuilder array(builder); 24 | array.add_array(vec); 25 | builder.Finish(array.Finish()); 26 | std::ofstream file(filename); 27 | file.write(reinterpret_cast(builder.GetBufferPointer()), builder.GetSize()); 28 | } 29 | 30 | while (state.KeepRunning()) 31 | { 32 | MMappedFileRead file(filename); 33 | const tfb::Array * read_array = tfb::GetArray(file.get_bytes().begin()); 34 | auto array = read_array->array(); 35 | int count = 0; 36 | for (auto it = array->begin(), end = array->end(); it != end; ++it) 37 | { 38 | RAW_ASSERT(it->vec()->x() == 0.0f); 39 | RAW_ASSERT(it->vec()->y() == 0.0f); 40 | RAW_ASSERT(it->vec()->z() == 0.0f); 41 | RAW_ASSERT(it->vec()->w() == 0.0f); 42 | RAW_ASSERT(it->f() == float(count)); 43 | RAW_ASSERT(it->i() == count % 5); 44 | ++count; 45 | } 46 | RAW_ASSERT(count == 100000); 47 | file.close_and_evict_from_os_cache(); 48 | } 49 | } 50 | //BENCHMARK(FlatbuffersReading); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/metav3/metav3_stl_map.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "metav3/metav3.hpp" 5 | 6 | namespace metav3 7 | { 8 | template 9 | struct MetaType::MetaTypeConstructor> 10 | { 11 | static const MetaType type; 12 | }; 13 | template 14 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterMap>(); 15 | template 16 | struct MetaType::MetaTypeConstructor> 17 | { 18 | static const MetaType type; 19 | }; 20 | template 21 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterMap>(); 22 | template 23 | struct MetaType::MapInfo::Creator> 24 | { 25 | static MapInfo Create() 26 | { 27 | typedef std::multimap Self; 28 | return 29 | { 30 | GetMetaType(), 31 | GetMetaType(), 32 | [](ConstMetaReference object) -> size_t 33 | { 34 | return object.Get().size(); 35 | }, 36 | [](MetaReference object, MetaReference && key, MetaReference && value) -> std::pair 37 | { 38 | return { object.Get().insert(std::make_pair(std::move(key.Get()), std::move(value.Get()))), true }; 39 | }, 40 | [](ConstMetaReference object) -> MapIterator 41 | { 42 | return const_cast(object.Get()).begin(); 43 | }, 44 | [](ConstMetaReference object) -> MapIterator 45 | { 46 | return const_cast(object.Get()).end(); 47 | } 48 | }; 49 | } 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /libs/benchmark/src/re.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef BENCHMARK_RE_H_ 16 | #define BENCHMARK_RE_H_ 17 | 18 | #if defined(HAVE_STD_REGEX) 19 | #include 20 | #elif defined(HAVE_GNU_POSIX_REGEX) 21 | #include 22 | #elif defined(HAVE_POSIX_REGEX) 23 | #include 24 | #else 25 | #error No regular expression backend was found! 26 | #endif 27 | #include 28 | 29 | namespace benchmark { 30 | 31 | // A wrapper around the POSIX regular expression API that provides automatic 32 | // cleanup 33 | class Regex { 34 | public: 35 | Regex(); 36 | ~Regex(); 37 | 38 | // Compile a regular expression matcher from spec. Returns true on success. 39 | // 40 | // On failure (and if error is not nullptr), error is populated with a human 41 | // readable error message if an error occurs. 42 | bool Init(const std::string& spec, std::string* error); 43 | 44 | // Returns whether str matches the compiled regular expression. 45 | bool Match(const std::string& str); 46 | private: 47 | bool init_; 48 | // Underlying regular expression object 49 | #if defined(HAVE_STD_REGEX) 50 | std::regex re_; 51 | #elif defined(HAVE_POSIX_REGEX) || defined(HAVE_GNU_POSIX_REGEX) 52 | regex_t re_; 53 | #else 54 | # error No regular expression backend implementation available 55 | #endif 56 | }; 57 | 58 | } // end namespace benchmark 59 | 60 | #endif // BENCHMARK_RE_H_ 61 | -------------------------------------------------------------------------------- /libs/benchmark/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | configuration: 4 | - Static Debug 5 | - Static Release 6 | # - Shared Debug 7 | # - Shared Release 8 | 9 | platform: 10 | - x86 11 | - x64 12 | 13 | environment: 14 | matrix: 15 | - compiler: gcc-4.9.2-posix 16 | # - compiler: gcc-4.8.4-posix 17 | # - compiler: msvc-12-seh 18 | 19 | install: 20 | # derive some extra information 21 | - for /f "tokens=1-2" %%a in ("%configuration%") do (@set "linkage=%%a") 22 | - for /f "tokens=1-2" %%a in ("%configuration%") do (@set "variant=%%b") 23 | - if "%linkage%"=="Shared" (set shared=YES) else (set shared=NO) 24 | - for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_name=%%a") 25 | - for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_version=%%b") 26 | - for /f "tokens=1-3 delims=-" %%a in ("%compiler%") do (@set "compiler_threading=%%c") 27 | - if "%platform%"=="x64" (set arch=x86_64) 28 | - if "%platform%"=="x86" (set arch=i686) 29 | # download the specific version of MinGW 30 | - if "%compiler_name%"=="gcc" (for /f %%a in ('python mingw.py --quiet --version "%compiler_version%" --arch "%arch%" --threading "%compiler_threading%" --location "C:\mingw-builds"') do @set "compiler_path=%%a") 31 | 32 | before_build: 33 | # Set up mingw commands 34 | - if "%compiler_name%"=="gcc" (set "generator=MinGW Makefiles") 35 | - if "%compiler_name%"=="gcc" (set "build=mingw32-make -j4") 36 | - if "%compiler_name%"=="gcc" (set "test=mingw32-make CTEST_OUTPUT_ON_FAILURE=1 test") 37 | # msvc specific commands 38 | # TODO :) 39 | # add the compiler path if needed 40 | - if not "%compiler_path%"=="" (set "PATH=%PATH%;%compiler_path%") 41 | # git bash conflicts with MinGW makefiles 42 | - if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files (x86)\Git\bin=%") 43 | 44 | build_script: 45 | - cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%variant%" "-DBUILD_SHARED_LIBS=%shared%" 46 | - cmd /c "%build%" 47 | 48 | test_script: 49 | - cmd /c "%test%" 50 | 51 | matrix: 52 | fast_finish: true 53 | 54 | cache: 55 | - C:\mingw-builds 56 | -------------------------------------------------------------------------------- /src/meta/metaStlMap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "meta/meta.hpp" 5 | 6 | namespace meta 7 | { 8 | template 9 | struct MetaType::MetaTypeConstructor> 10 | { 11 | static const MetaType type; 12 | }; 13 | template 14 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterMap>(); 15 | template 16 | struct MetaType::MetaTypeConstructor> 17 | { 18 | static const MetaType type; 19 | }; 20 | template 21 | const MetaType MetaType::MetaTypeConstructor>::type = MetaType::RegisterMap>(); 22 | template 23 | struct MetaType::MapInfo::Creator> 24 | { 25 | static MapInfo Create() 26 | { 27 | typedef std::multimap Self; 28 | return 29 | { 30 | GetMetaType(), 31 | GetMetaType(), 32 | [](const MetaReference & object) -> size_t 33 | { 34 | return object.Get().size(); 35 | }, 36 | [](const MetaReference & object, const MetaReference & element) -> std::pair 37 | { 38 | return const_cast(object.Get()).equal_range(element.Get()); 39 | }, 40 | [](MetaReference & object, MapIterator it) -> MapIterator 41 | { 42 | return object.Get().erase(*it.target()); 43 | }, 44 | [](MetaReference & object, MetaReference && key, MetaReference && value) -> std::pair 45 | { 46 | return { object.Get().insert(std::make_pair(std::move(key.Get()), std::move(value.Get()))), true }; 47 | }, 48 | [](const MetaReference & object) -> MapIterator 49 | { 50 | return const_cast(object.Get()).begin(); 51 | }, 52 | [](const MetaReference & object) -> MapIterator 53 | { 54 | return const_cast(object.Get()).end(); 55 | } 56 | }; 57 | } 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /src/os/memoryManager.cpp: -------------------------------------------------------------------------------- 1 | #include "memoryManager.hpp" 2 | #include 3 | #include "debug/assert.hpp" 4 | #include 5 | #include 6 | 7 | namespace mem 8 | { 9 | 10 | std::atomic num_allocations(0); 11 | std::atomic num_frees(0); 12 | std::atomic bytes_allocated(0); 13 | 14 | size_t MemoryManager::GetNumAllocations() 15 | { 16 | return num_allocations; 17 | } 18 | 19 | size_t MemoryManager::GetNumFrees() 20 | { 21 | return num_frees; 22 | } 23 | 24 | size_t MemoryManager::GetTotalBytesAllocated() 25 | { 26 | return bytes_allocated; 27 | } 28 | 29 | void * AllocAligned(size_t size, size_t alignment) 30 | { 31 | unsigned char * allocated = static_cast(::operator new(size + alignment)); 32 | unsigned char * result = allocated + alignment - reinterpret_cast(allocated) % alignment; 33 | *reinterpret_cast(result - sizeof(void *)) = allocated; 34 | return result; 35 | } 36 | 37 | void FreeAligned(void * ptr) 38 | { 39 | if (!ptr) return; 40 | ::operator delete(*reinterpret_cast(static_cast(ptr) - sizeof(void *))); 41 | } 42 | } 43 | 44 | #if defined(__has_feature) 45 | # if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer) 46 | # define NO_CUSTOM_OPERATOR_NEW 47 | # endif 48 | #endif 49 | #ifndef NO_CUSTOM_OPERATOR_NEW 50 | void * operator new(size_t num_bytes) 51 | { 52 | ++mem::num_allocations; 53 | mem::bytes_allocated += num_bytes; 54 | return malloc(num_bytes); 55 | } 56 | void * operator new[](size_t num_bytes) 57 | { 58 | ++mem::num_allocations; 59 | mem::bytes_allocated += num_bytes; 60 | return malloc(num_bytes); 61 | } 62 | 63 | void operator delete(void * ptr) noexcept 64 | { 65 | if (ptr) 66 | { 67 | ++mem::num_frees; 68 | free(ptr); 69 | } 70 | } 71 | void operator delete(void * ptr, size_t) noexcept 72 | { 73 | ::operator delete(ptr); 74 | } 75 | void operator delete[](void * ptr) noexcept 76 | { 77 | ::operator delete(ptr); 78 | } 79 | void operator delete[](void * ptr, size_t) noexcept 80 | { 81 | ::operator delete[](ptr); 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /libs/benchmark/test/filter_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace { 14 | 15 | class TestReporter : public benchmark::ConsoleReporter { 16 | public: 17 | virtual bool ReportContext(const Context& context) { 18 | return ConsoleReporter::ReportContext(context); 19 | }; 20 | 21 | virtual void ReportRuns(const std::vector& report) { 22 | ++count_; 23 | ConsoleReporter::ReportRuns(report); 24 | }; 25 | 26 | TestReporter() : count_(0) {} 27 | 28 | virtual ~TestReporter() {} 29 | 30 | size_t GetCount() const { 31 | return count_; 32 | } 33 | 34 | private: 35 | mutable size_t count_; 36 | }; 37 | 38 | } // end namespace 39 | 40 | 41 | static void NoPrefix(benchmark::State& state) { 42 | while (state.KeepRunning()) {} 43 | } 44 | BENCHMARK(NoPrefix); 45 | 46 | static void BM_Foo(benchmark::State& state) { 47 | while (state.KeepRunning()) {} 48 | } 49 | BENCHMARK(BM_Foo); 50 | 51 | 52 | static void BM_Bar(benchmark::State& state) { 53 | while (state.KeepRunning()) {} 54 | } 55 | BENCHMARK(BM_Bar); 56 | 57 | 58 | static void BM_FooBar(benchmark::State& state) { 59 | while (state.KeepRunning()) {} 60 | } 61 | BENCHMARK(BM_FooBar); 62 | 63 | 64 | static void BM_FooBa(benchmark::State& state) { 65 | while (state.KeepRunning()) {} 66 | } 67 | BENCHMARK(BM_FooBa); 68 | 69 | 70 | 71 | int main(int argc, char* argv[]) { 72 | benchmark::Initialize(&argc, argv); 73 | 74 | TestReporter test_reporter; 75 | benchmark::RunSpecifiedBenchmarks(&test_reporter); 76 | 77 | if (argc == 2) { 78 | // Make sure we ran all of the tests 79 | std::stringstream ss(argv[1]); 80 | size_t expected; 81 | ss >> expected; 82 | 83 | const size_t count = test_reporter.GetCount(); 84 | if (count != expected) { 85 | std::cerr << "ERROR: Expected " << expected << " tests to be ran but only " 86 | << count << " completed" << std::endl; 87 | return -1; 88 | } 89 | } 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /libs/gtest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // Google C++ Testing Framework (Google Test) 33 | // 34 | // Sometimes it's desirable to build Google Test by compiling a single file. 35 | // This file serves this purpose. 36 | 37 | // This line ensures that gtest.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gtest/gtest.h" 40 | 41 | // The following lines pull in the real gtest *.cc files. 42 | #include "src/gtest.cc" 43 | #include "src/gtest-death-test.cc" 44 | #include "src/gtest-filepath.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /src/debug/assert_settings.cpp: -------------------------------------------------------------------------------- 1 | #include "assert_settings.hpp" 2 | #include 3 | 4 | namespace assert 5 | { 6 | namespace 7 | { 8 | struct AssertCallbackStorage 9 | { 10 | AssertCallbackStorage() 11 | : assert_callback([](const AssertContext & context) 12 | { 13 | std::cerr << "Assertion failed in file \"" << context.file << "\" line " << context.line <<":\n" << context.condition << std::endl; 14 | return ShouldBreak; 15 | }) 16 | { 17 | } 18 | 19 | std::function assert_callback; 20 | }; 21 | } 22 | static AssertCallbackStorage & assert_callback_storage() 23 | { 24 | static AssertCallbackStorage storage; 25 | return storage; 26 | } 27 | 28 | std::function SetAssertCallback(std::function callback) 29 | { 30 | using std::swap; 31 | swap(assert_callback_storage().assert_callback, callback); 32 | return callback; 33 | } 34 | const std::function & GetAssertCallback() 35 | { 36 | return assert_callback_storage().assert_callback; 37 | } 38 | } 39 | 40 | #if !defined(DISABLE_TESTS) && !defined(FINAL) 41 | #include 42 | 43 | #ifdef RUN_SLOW_TESTS 44 | static std::string escape_for_regex(const char * message) 45 | { 46 | std::string result; 47 | for (const char * c = message; c && *c; ++c) 48 | { 49 | switch(*c) 50 | { 51 | case '.': 52 | result.push_back('\\'); 53 | result.push_back('.'); 54 | break; 55 | case '\\': 56 | result.push_back('\\'); 57 | result.push_back('\\'); 58 | break; 59 | default: 60 | result.push_back(*c); 61 | break; 62 | } 63 | } 64 | return result; 65 | } 66 | 67 | TEST(assert_settingsDeathTest, default_crashes) 68 | { 69 | bool assert_condition = true; 70 | auto dying_function = [&]{ DE_ASSERT(!assert_condition); }; 71 | ASSERT_DEATH(dying_function(), escape_for_regex(__FILE__ ) + ".*" + std::to_string(__LINE__ - 1) + ".*!assert_condition.*"); 72 | } 73 | #endif 74 | 75 | TEST(assert_settings, disable_breakpoint) 76 | { 77 | bool did_assert = false; 78 | ::assert::ScopedSetAssertCallback change_callback([&](const ::assert::AssertContext &) 79 | { 80 | did_assert = true; 81 | return ::assert::ShouldNotBreak; 82 | }); 83 | RAW_ASSERT(false); 84 | ASSERT_TRUE(did_assert); 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /src/util/compressed_buffer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "util/view.hpp" 5 | #include "util/stl_container_forward.hpp" 6 | 7 | struct CompressedBuffer 8 | { 9 | // lz4_compression_level goes from 0 to 16, with 1 being the least compressed, 16 being 10 | // the most compressed, and 0 being a special value meaning "use default value." 11 | // I'm not sure what it actually means. looking at the source code it looks like it 12 | // doubles some "number of attempts" with every increase. meaning when it's 10, that 13 | // number is twice as high as when compression_level 9. so maybe the worst case takes twice 14 | // as long every time that you double this... 15 | // lz4 recommends values between 4 and 9, and currently 0 makes it default to 9 16 | CompressedBuffer(ArrayView bytes, int lz4_compression_level = 0); 17 | CompressedBuffer(StringView bytes, int lz4_compression_level = 0); 18 | 19 | // the above functions will allocate too much. this function 20 | // will reallocate the buffer to the size that will be returned by get_bytes() 21 | void shrink_to_fit(); 22 | // indicates how much smaller the internal buffer would be after calling shrink_to_fit 23 | // compared to the buffer originally allocated 24 | size_t shrink_to_fit_savings() const; 25 | 26 | ArrayView get_bytes() const 27 | { 28 | return { buffer.get(), buffer.get() + size }; 29 | } 30 | 31 | private: 32 | std::unique_ptr buffer; 33 | size_t size; 34 | }; 35 | 36 | struct UncompressedBuffer 37 | { 38 | UncompressedBuffer(ArrayView compressed_bytes); 39 | 40 | ArrayView get_bytes() const 41 | { 42 | return { buffer.get(), buffer.get() + size }; 43 | } 44 | ArrayView get_bytes() 45 | { 46 | return { buffer.get(), buffer.get() + size }; 47 | } 48 | StringView get_text() const 49 | { 50 | const char * begin = reinterpret_cast(buffer.get()); 51 | return { begin, begin + size }; 52 | } 53 | StringView get_text() 54 | { 55 | char * begin = reinterpret_cast(buffer.get()); 56 | return { begin, begin + size }; 57 | } 58 | 59 | private: 60 | std::unique_ptr buffer; 61 | uint64_t size; 62 | }; 63 | -------------------------------------------------------------------------------- /libs/gtest/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | // 32 | // Google C++ Testing Framework definitions useful in production code. 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void MyMethod(); 44 | // FRIEND_TEST(MyClassTest, MyMethod); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, MyMethod) { 52 | // // Can call MyClass::MyMethod() here. 53 | // } 54 | 55 | #define FRIEND_TEST(test_case_name, test_name)\ 56 | friend class test_case_name##_##test_name##_Test 57 | 58 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 59 | -------------------------------------------------------------------------------- /src/util/memoizingMap.cpp: -------------------------------------------------------------------------------- 1 | #include "memoizingMap.hpp" 2 | 3 | 4 | #ifndef DISABLE_GTEST 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace 12 | { 13 | struct test_exception 14 | { 15 | }; 16 | 17 | struct throw_exception_once 18 | { 19 | throw_exception_once() 20 | { 21 | if (!threw.exchange(true)) 22 | { 23 | throw test_exception(); 24 | } 25 | } 26 | 27 | private: 28 | static std::atomic threw; 29 | }; 30 | std::atomic throw_exception_once::threw(false); 31 | } 32 | 33 | // call_once doesn't work... 34 | TEST(call_once, DISABLED_exception) 35 | { 36 | std::once_flag once; 37 | try 38 | { 39 | std::call_once(once, []{ throw 5; }); 40 | } 41 | catch(int) 42 | { 43 | } 44 | int b = 0; 45 | std::call_once(once, [&b]{ b = 5; }); 46 | ASSERT_EQ(5, b); 47 | } 48 | 49 | // re-enable when the test above this works again 50 | TEST(memoizing_map, DISABLED_exception) 51 | { 52 | struct compare_ok 53 | { 54 | compare_ok(std::atomic & signal_ok, std::atomic & to_wait_for) 55 | : signal_ok(signal_ok), to_wait_for(to_wait_for) 56 | { 57 | } 58 | bool operator<(const compare_ok &) const 59 | { 60 | signal_ok = true; 61 | while (!to_wait_for) {} 62 | return false; 63 | } 64 | 65 | private: 66 | std::atomic & signal_ok; 67 | std::atomic & to_wait_for; 68 | }; 69 | 70 | memoizing_map throwing_map; 71 | std::promise signal_second; 72 | std::atomic signal_first(false); 73 | std::atomic did_throw(false); 74 | std::exception_ptr first_exception; 75 | std::thread a([&] 76 | { 77 | try 78 | { 79 | throwing_map.get(compare_ok(signal_first, did_throw), [&](const compare_ok &) 80 | { 81 | signal_second.set_value(); 82 | while (!signal_first) {}; 83 | return throw_exception_once(); 84 | }); 85 | } 86 | catch(...) 87 | { 88 | first_exception = std::current_exception(); 89 | did_throw = true; 90 | } 91 | }); 92 | signal_second.get_future().get(); 93 | std::thread b([&] 94 | { 95 | throwing_map.get(compare_ok(signal_first, did_throw), [&](const compare_ok &) 96 | { 97 | return throw_exception_once(); 98 | }); 99 | }); 100 | a.join(); 101 | b.join(); 102 | ASSERT_THROW(std::rethrow_exception(std::move(first_exception)), test_exception); 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /src/debug/assert.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DEBUG_BREAK() do { __asm__("int $3"); } while (false) 4 | #define DEBUG_BREAK_IF_DEBUGGER_ATTACHED() do { ::assert::detail::BreakOnlyIfDebuggerAttached break_guard; DEBUG_BREAK(); } while (false) 5 | namespace assert 6 | { 7 | enum AssertBreakPoint 8 | { 9 | ShouldBreakIfDebuggerAttached, 10 | ShouldBreak, 11 | ShouldNotBreak 12 | }; 13 | struct AssertContext 14 | { 15 | const char * file; 16 | int line; 17 | const char * condition; 18 | }; 19 | 20 | namespace detail 21 | { 22 | #ifndef CLANG_ANALYZER_NORETURN 23 | # ifdef __has_feature 24 | # if __has_feature(attribute_analyzer_noreturn) 25 | # define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) 26 | # else 27 | # define CLANG_ANALYZER_NORETURN 28 | # endif 29 | # else 30 | # define CLANG_ANALYZER_NORETURN 31 | # endif 32 | #endif 33 | 34 | CLANG_ANALYZER_NORETURN AssertBreakPoint OnAssert(const AssertContext & context); 35 | 36 | struct BreakOnlyIfDebuggerAttached 37 | { 38 | BreakOnlyIfDebuggerAttached(); 39 | ~BreakOnlyIfDebuggerAttached(); 40 | private: 41 | void (*old_signal_handler)(int); 42 | }; 43 | } 44 | struct ScopedSetBreakOnThrow 45 | { 46 | ScopedSetBreakOnThrow(bool value); 47 | ~ScopedSetBreakOnThrow(); 48 | static bool break_on_throw(); 49 | private: 50 | bool old_value; 51 | }; 52 | } 53 | 54 | #define UNLIKELY(x) __builtin_expect(static_cast(x), false) 55 | 56 | #ifdef FINAL 57 | # define RAW_ASSERT(condition, ...) static_cast(0) 58 | #else 59 | # define RAW_ASSERT(condition, ...) \ 60 | if (UNLIKELY(!(condition)))\ 61 | {\ 62 | ::assert::AssertContext context = { __FILE__, __LINE__, #condition };\ 63 | ::assert::AssertBreakPoint should_break = ::assert::detail::OnAssert(context);\ 64 | if (should_break == ::assert::ShouldBreakIfDebuggerAttached)\ 65 | DEBUG_BREAK_IF_DEBUGGER_ATTACHED();\ 66 | else if (should_break == ::assert::ShouldBreak)\ 67 | DEBUG_BREAK();\ 68 | }\ 69 | else\ 70 | static_cast(0) 71 | #endif 72 | 73 | #ifdef FINAL 74 | # define RAW_VERIFY(condition, ...) if (condition) static_cast(0); else static_cast(0) 75 | #else 76 | # define RAW_VERIFY(condition, ...) RAW_ASSERT(condition, __VA_ARGS__) 77 | #endif 78 | 79 | #ifdef FINAL 80 | # define RAW_THROW(exception) throw exception 81 | #else 82 | # define RAW_THROW(exception) do { if (::assert::ScopedSetBreakOnThrow::break_on_throw()) DEBUG_BREAK_IF_DEBUGGER_ATTACHED(); throw exception; } while (false) 83 | #endif 84 | 85 | #define CHECK_FOR_PROGRAMMER_ERROR(condition, ...) RAW_ASSERT(condition, __VA_ARGS__) 86 | #define CHECK_FOR_INVALID_DATA(condition, ...) RAW_ASSERT(condition, __VA_ARGS__) 87 | -------------------------------------------------------------------------------- /libs/benchmark/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute # 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | a just a few small guidelines you need to follow. 5 | 6 | 7 | ## Contributor License Agreement ## 8 | 9 | Contributions to any Google project must be accompanied by a Contributor 10 | License Agreement. This is not a copyright **assignment**, it simply gives 11 | Google permission to use and redistribute your contributions as part of the 12 | project. 13 | 14 | * If you are an individual writing original source code and you're sure you 15 | own the intellectual property, then you'll need to sign an [individual 16 | CLA][]. 17 | 18 | * If you work for a company that wants to allow you to contribute your work, 19 | then you'll need to sign a [corporate CLA][]. 20 | 21 | You generally only need to submit a CLA once, so if you've already submitted 22 | one (even if it was for a different project), you probably don't need to do it 23 | again. 24 | 25 | [individual CLA]: https://developers.google.com/open-source/cla/individual 26 | [corporate CLA]: https://developers.google.com/open-source/cla/corporate 27 | 28 | Once your CLA is submitted (or if you already submitted one for 29 | another Google project), make a commit adding yourself to the 30 | [AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part 31 | of your first [pull request][]. 32 | 33 | [AUTHORS]: AUTHORS 34 | [CONTRIBUTORS]: CONTRIBUTORS 35 | 36 | 37 | ## Submitting a patch ## 38 | 39 | 1. It's generally best to start by opening a new issue describing the bug or 40 | feature you're intending to fix. Even if you think it's relatively minor, 41 | it's helpful to know what people are working on. Mention in the initial 42 | issue that you are planning to work on that bug or feature so that it can 43 | be assigned to you. 44 | 45 | 1. Follow the normal process of [forking][] the project, and setup a new 46 | branch to work in. It's important that each group of changes be done in 47 | separate branches in order to ensure that a pull request only includes the 48 | commits related to that bug or feature. 49 | 50 | 1. Do your best to have [well-formed commit messages][] for each change. 51 | This provides consistency throughout the project, and ensures that commit 52 | messages are able to be formatted properly by various git tools. 53 | 54 | 1. Finally, push the commits to your fork and submit a [pull request][]. 55 | 56 | [forking]: https://help.github.com/articles/fork-a-repo 57 | [well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 58 | [pull request]: https://help.github.com/articles/creating-a-pull-request 59 | -------------------------------------------------------------------------------- /src/util/algorithm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | // like std::binary_search, but returns the iterator to the element 5 | // if it was found, and returns end otherwise 6 | template 7 | It binary_find(It begin, It end, const T & value) 8 | { 9 | auto lower_bound = std::lower_bound(begin, end, value); 10 | if (lower_bound == end || value < *lower_bound) return end; 11 | else return lower_bound; 12 | } 13 | // like std::binary_search, but returns the iterator to the element 14 | // if it was found, and returns end otherwise 15 | template 16 | It binary_find(It begin, It end, const T & value, const Compare & cmp) 17 | { 18 | auto lower_bound = std::lower_bound(begin, end, value, cmp); 19 | if (lower_bound == end || cmp(value, *lower_bound)) return end; 20 | else return lower_bound; 21 | } 22 | 23 | // like std::accumulate but only one temporary gets created and the functor 24 | // is expected to update that temporary. 25 | template 26 | T foldl(It begin, It end, T object, const Func & func) 27 | { 28 | for (; begin != end; ++begin) 29 | { 30 | func(object, *begin); 31 | } 32 | return object; 33 | } 34 | // adaptor of the above function which takes range 35 | template 36 | T foldl(const Range & range, T object, const Func & func) 37 | { 38 | using std::begin; using std::end; 39 | return foldl(begin(range), end(range), std::move(object), func); 40 | } 41 | 42 | // will copy from the input iterator as long as the condition holds true 43 | template 44 | Out copy_while(It from, Out to, const Func & condition) 45 | { 46 | while (condition(*from)) 47 | { 48 | *to++ = *from++; 49 | } 50 | return to; 51 | } 52 | 53 | namespace detail 54 | { 55 | template 56 | T power_accumulate_positive(T r, T a, size_t exponent, const Func & func) 57 | { 58 | while (true) 59 | { 60 | if (exponent % 2) 61 | { 62 | r = func(r, a); 63 | if (exponent == 1) return r; 64 | } 65 | a = func(a, a); 66 | exponent /= 2; 67 | } 68 | } 69 | } 70 | template 71 | T power_positive(T base, size_t exponent, const Func & func) 72 | { 73 | while (!(exponent % 2)) 74 | { 75 | base = func(base, base); 76 | exponent /= 2; 77 | } 78 | exponent /= 2; 79 | if (exponent == 0) return base; 80 | else return detail::power_accumulate_positive(base, func(base, base), exponent, func); 81 | } 82 | template 83 | inline T power(T base, size_t exponent, const Func & func, T id) 84 | { 85 | if (exponent == 0) return id; 86 | else return power_positive(base, exponent, func); 87 | } 88 | -------------------------------------------------------------------------------- /src/os/mmapped_file.cpp: -------------------------------------------------------------------------------- 1 | #include "os/mmapped_file.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | const int UnixFile::RDONLY = O_RDONLY; 9 | const int UnixFile::RDWR = O_RDWR; 10 | const int UnixFile::WRONLY = O_WRONLY; 11 | 12 | UnixFile::UnixFile(StringView filename, int flags) 13 | : file_descriptor(open(filename.begin(), flags)) 14 | { 15 | } 16 | UnixFile::UnixFile(StringView filename, int flags, int mode) 17 | : file_descriptor(open(filename.begin(), flags, mode)) 18 | { 19 | } 20 | UnixFile::~UnixFile() 21 | { 22 | if (file_descriptor >= 0) 23 | close(file_descriptor); 24 | } 25 | void UnixFile::evict_from_os_cache() 26 | { 27 | fdatasync(file_descriptor); 28 | posix_fadvise(file_descriptor, 0, 0, POSIX_FADV_DONTNEED); 29 | } 30 | 31 | size_t UnixFile::size() 32 | { 33 | off_t end = lseek(file_descriptor, 0, SEEK_END); 34 | off_t begin = lseek(file_descriptor, 0, SEEK_SET); 35 | return end - begin; 36 | } 37 | size_t UnixFile::read(ArrayView bytes) 38 | { 39 | return ::read(file_descriptor, bytes.begin(), bytes.size()); 40 | } 41 | 42 | struct MMappedFileRead::Internals 43 | { 44 | Internals(StringView filename) 45 | : file(filename, O_RDONLY) 46 | { 47 | if (!file.is_valid()) 48 | return; 49 | struct stat file_info; 50 | if (fstat(file.file_descriptor, &file_info) == -1 || !file_info.st_size) 51 | return; 52 | void * mapped = mmap(nullptr, file_info.st_size, PROT_READ, MAP_PRIVATE, file.file_descriptor, 0); 53 | if (!mapped) 54 | return; 55 | if (file_info.st_size == 0) 56 | { 57 | munmap(mapped, 0); 58 | return; 59 | } 60 | file_contents = { static_cast(mapped), static_cast(mapped) + file_info.st_size }; 61 | } 62 | ~Internals() 63 | { 64 | if (!file_contents.empty()) 65 | munmap(file_contents.begin(), file_contents.size()); 66 | } 67 | 68 | UnixFile file; 69 | ArrayView file_contents; 70 | }; 71 | 72 | MMappedFileRead::MMappedFileRead(StringView filename) 73 | : internals(new Internals(filename)) 74 | { 75 | } 76 | MMappedFileRead::~MMappedFileRead() = default; 77 | 78 | ArrayView MMappedFileRead::get_bytes() const 79 | { 80 | return internals->file_contents; 81 | } 82 | 83 | void MMappedFileRead::close_and_evict_from_os_cache() 84 | { 85 | if (!internals->file_contents.empty()) 86 | { 87 | munmap(internals->file_contents.begin(), internals->file_contents.size()); 88 | internals->file_contents = {}; 89 | } 90 | if (internals->file.is_valid()) 91 | internals->file.evict_from_os_cache(); 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/util/compressed_buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "util/compressed_buffer.hpp" 2 | #include "lz4.h" 3 | #include "lz4hc.h" 4 | 5 | CompressedBuffer::CompressedBuffer(ArrayView bytes, int lz4_compression_level) 6 | { 7 | int compressed_bound = LZ4_compressBound(int(bytes.size())); 8 | int size_extra_space = sizeof(uint64_t); 9 | 10 | buffer.reset(new unsigned char[compressed_bound + size_extra_space]); 11 | *reinterpret_cast(buffer.get()) = bytes.size(); 12 | size = size_extra_space; 13 | 14 | size += LZ4_compress_HC(reinterpret_cast(bytes.begin()), reinterpret_cast(buffer.get() + size_extra_space), bytes.size(), compressed_bound, lz4_compression_level); 15 | } 16 | CompressedBuffer::CompressedBuffer(StringView text, int lz4_compression_level) 17 | : CompressedBuffer(ArrayView(reinterpret_cast(text.begin()), reinterpret_cast(text.end())), lz4_compression_level) 18 | { 19 | } 20 | 21 | void CompressedBuffer::shrink_to_fit() 22 | { 23 | std::unique_ptr replacement(new unsigned char[size]); 24 | std::copy(buffer.get(), buffer.get() + size, replacement.get()); 25 | buffer = std::move(replacement); 26 | } 27 | size_t CompressedBuffer::shrink_to_fit_savings() const 28 | { 29 | return LZ4_compressBound(*reinterpret_cast(buffer.get())) + sizeof(uint64_t) - size; 30 | } 31 | 32 | UncompressedBuffer::UncompressedBuffer(ArrayView compressed_bytes) 33 | : size(*reinterpret_cast(compressed_bytes.begin())) 34 | { 35 | buffer.reset(new unsigned char[size]); 36 | LZ4_decompress_safe(reinterpret_cast(compressed_bytes.begin() + sizeof(uint64_t)), reinterpret_cast(buffer.get()), compressed_bytes.size() - sizeof(uint64_t), size); 37 | } 38 | 39 | #ifndef DISABLE_GTEST 40 | #include 41 | TEST(compressed_buffer, roundtrip) 42 | { 43 | unsigned char bytes[] = { 1, 2, 3, 4, 1, 2, 3, 4 }; 44 | ArrayView as_view = bytes; 45 | CompressedBuffer compressed(as_view); 46 | UncompressedBuffer uncompressed(compressed.get_bytes()); 47 | ASSERT_EQ(as_view, uncompressed.get_bytes()); 48 | } 49 | TEST(compressed_buffer, string_roundtrip) 50 | { 51 | std::string text = "hello, world!"; 52 | CompressedBuffer compressed(text); 53 | UncompressedBuffer uncompressed(compressed.get_bytes()); 54 | ASSERT_EQ(text, uncompressed.get_text()); 55 | } 56 | TEST(compressed_buffer, shrink_to_fit) 57 | { 58 | unsigned char bytes[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4 }; 59 | ArrayView as_view = bytes; 60 | CompressedBuffer compressed(as_view); 61 | ASSERT_GT(compressed.shrink_to_fit_savings(), 0u); 62 | compressed.shrink_to_fit(); 63 | UncompressedBuffer uncompressed(compressed.get_bytes()); 64 | ASSERT_EQ(as_view, uncompressed.get_bytes()); 65 | } 66 | 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /libs/benchmark/test/basic_test.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "benchmark/benchmark_api.h" 3 | 4 | #define BASIC_BENCHMARK_TEST(x) \ 5 | BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192) 6 | 7 | void BM_empty(benchmark::State& state) { 8 | while (state.KeepRunning()) { 9 | benchmark::DoNotOptimize(state.iterations()); 10 | } 11 | } 12 | BENCHMARK(BM_empty); 13 | BENCHMARK(BM_empty)->ThreadPerCpu(); 14 | 15 | void BM_spin_empty(benchmark::State& state) { 16 | while (state.KeepRunning()) { 17 | for (int x = 0; x < state.range_x(); ++x) { 18 | benchmark::DoNotOptimize(x); 19 | } 20 | } 21 | } 22 | BASIC_BENCHMARK_TEST(BM_spin_empty); 23 | BASIC_BENCHMARK_TEST(BM_spin_empty)->ThreadPerCpu(); 24 | 25 | void BM_spin_pause_before(benchmark::State& state) { 26 | for (int i = 0; i < state.range_x(); ++i) { 27 | benchmark::DoNotOptimize(i); 28 | } 29 | while(state.KeepRunning()) { 30 | for (int i = 0; i < state.range_x(); ++i) { 31 | benchmark::DoNotOptimize(i); 32 | } 33 | } 34 | } 35 | BASIC_BENCHMARK_TEST(BM_spin_pause_before); 36 | BASIC_BENCHMARK_TEST(BM_spin_pause_before)->ThreadPerCpu(); 37 | 38 | 39 | void BM_spin_pause_during(benchmark::State& state) { 40 | while(state.KeepRunning()) { 41 | state.PauseTiming(); 42 | for (int i = 0; i < state.range_x(); ++i) { 43 | benchmark::DoNotOptimize(i); 44 | } 45 | state.ResumeTiming(); 46 | for (int i = 0; i < state.range_x(); ++i) { 47 | benchmark::DoNotOptimize(i); 48 | } 49 | } 50 | } 51 | BASIC_BENCHMARK_TEST(BM_spin_pause_during); 52 | BASIC_BENCHMARK_TEST(BM_spin_pause_during)->ThreadPerCpu(); 53 | 54 | void BM_pause_during(benchmark::State& state) { 55 | while(state.KeepRunning()) { 56 | state.PauseTiming(); 57 | state.ResumeTiming(); 58 | } 59 | } 60 | BENCHMARK(BM_pause_during); 61 | BENCHMARK(BM_pause_during)->ThreadPerCpu(); 62 | BENCHMARK(BM_pause_during)->UseRealTime(); 63 | BENCHMARK(BM_pause_during)->UseRealTime()->ThreadPerCpu(); 64 | 65 | void BM_spin_pause_after(benchmark::State& state) { 66 | while(state.KeepRunning()) { 67 | for (int i = 0; i < state.range_x(); ++i) { 68 | benchmark::DoNotOptimize(i); 69 | } 70 | } 71 | for (int i = 0; i < state.range_x(); ++i) { 72 | benchmark::DoNotOptimize(i); 73 | } 74 | } 75 | BASIC_BENCHMARK_TEST(BM_spin_pause_after); 76 | BASIC_BENCHMARK_TEST(BM_spin_pause_after)->ThreadPerCpu(); 77 | 78 | 79 | void BM_spin_pause_before_and_after(benchmark::State& state) { 80 | for (int i = 0; i < state.range_x(); ++i) { 81 | benchmark::DoNotOptimize(i); 82 | } 83 | while(state.KeepRunning()) { 84 | for (int i = 0; i < state.range_x(); ++i) { 85 | benchmark::DoNotOptimize(i); 86 | } 87 | } 88 | for (int i = 0; i < state.range_x(); ++i) { 89 | benchmark::DoNotOptimize(i); 90 | } 91 | } 92 | BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after); 93 | BASIC_BENCHMARK_TEST(BM_spin_pause_before_and_after)->ThreadPerCpu(); 94 | 95 | 96 | void BM_empty_stop_start(benchmark::State& state) { 97 | while (state.KeepRunning()) { } 98 | } 99 | BENCHMARK(BM_empty_stop_start); 100 | BENCHMARK(BM_empty_stop_start)->ThreadPerCpu(); 101 | 102 | BENCHMARK_MAIN() 103 | -------------------------------------------------------------------------------- /Tupfile.lua: -------------------------------------------------------------------------------- 1 | 2 | LINK_FLAGS += '-pthread' 3 | LINK_FLAGS += '-fuse-ld=gold' 4 | -- the next two lines are for incremental linking. 5 | -- they are turned off because they seem to be slower 6 | -- right now. maybe use it when the project gets bigger 7 | --LINK_FLAGS += '-Wl,--incremental' 8 | --LINK_FLAGS += '-fno-use-linker-plugin' 9 | 10 | LINK_LIBS += '-lprotobuf' 11 | LINK_LIBS += '-lboost_serialization' 12 | 13 | INPUT_FOLDERS = {} 14 | INPUT_FOLDERS += './' 15 | INPUT_FOLDERS += 'src/' 16 | INPUT_FOLDERS += 'src/debug/' 17 | INPUT_FOLDERS += 'src/flatbuffers/' 18 | INPUT_FOLDERS += 'src/meta/' 19 | INPUT_FOLDERS += 'src/meta/serialization/' 20 | INPUT_FOLDERS += 'src/metav3/' 21 | INPUT_FOLDERS += 'src/metav3/serialization/' 22 | INPUT_FOLDERS += 'src/metafast/' 23 | INPUT_FOLDERS += 'src/os/' 24 | INPUT_FOLDERS += 'src/protobuf/' 25 | INPUT_FOLDERS += 'src/util/' 26 | 27 | for _, v in ipairs(INPUT_FOLDERS) do 28 | CPP_SOURCES += tup.glob(v .. '*.cpp') 29 | end 30 | 31 | OUTPUT_FOLDERS = INPUT_FOLDERS 32 | 33 | CPP_SOURCES += 'libs/gtest/src/gtest-all.cc' 34 | OUTPUT_FOLDERS += 'libs/gtest/src/' 35 | CPP_SOURCES += tup.glob('libs/benchmark/src/*.cc') 36 | OUTPUT_FOLDERS += 'libs/benchmark/src/' 37 | C_SOURCES += tup.glob('libs/z4/*.c') 38 | OUTPUT_FOLDERS += 'libs/z4/' 39 | 40 | protobuf_headers = {} 41 | function compile_protobuf() 42 | protobuf_outputs = {} 43 | protobuf_inputs = {} 44 | cpp_outputs = {} 45 | for _, v in ipairs(tup.glob('src/protobuf/*.proto')) do 46 | protobuf_inputs += v 47 | no_ext = v:sub(1, #v - 6) 48 | cpp_output = no_ext .. '.pb.cc' 49 | h_output = no_ext .. '.pb.h' 50 | protobuf_outputs += { cpp_output, h_output } 51 | cpp_outputs += cpp_output 52 | protobuf_headers += h_output 53 | end 54 | tup.definerule{ inputs = protobuf_inputs, command = 'protoc -Isrc --cpp_out=src ' .. table.concat(protobuf_inputs, ' '), outputs = protobuf_outputs } 55 | for _, v in ipairs(cpp_outputs) do 56 | compile_cpp(v, protobuf_headers) 57 | end 58 | end 59 | compile_protobuf() 60 | 61 | flatbuffers_headers = {} 62 | function compile_flatbuffers() 63 | for _, v in ipairs(tup.glob('src/flatbuffers/*.idl')) do 64 | no_ext = v:sub(1, #v - 4) 65 | output = no_ext .. '_generated.h' 66 | out_folder = 'src/flatbuffers/' 67 | flatbuffers_headers += output 68 | tup.definerule{ inputs = v, command = '/home/malte/workspace/flatbuffers/flatc -c -o ' .. out_folder .. ' ' .. v, outputs = { output } } 69 | end 70 | end 71 | compile_flatbuffers() 72 | 73 | generated_headers = protobuf_headers 74 | generated_headers += flatbuffers_headers 75 | 76 | for i, v in ipairs(CPP_SOURCES) do 77 | compile_cpp(v, generated_headers) 78 | end 79 | for i, v in ipairs(C_SOURCES) do 80 | compile_c(v, generated_headers) 81 | end 82 | 83 | executable_name = 'main' 84 | 85 | objfiles = {} 86 | for _, v in ipairs(OUTPUT_FOLDERS) do 87 | objfiles += tup.glob(v .. '*.o') 88 | end 89 | tup.definerule{ inputs = objfiles, 90 | command = CPP_LINKER .. ' ' .. table.concat(LINK_FLAGS, ' ') .. ' ' .. table.concat(objfiles, ' ') .. ' ' .. table.concat(LINK_LIBS, ' ') .. ' -o ' .. executable_name, 91 | outputs = {executable_name} } 92 | -------------------------------------------------------------------------------- /libs/benchmark/src/commandlineflags.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_COMMANDLINEFLAGS_H_ 2 | #define BENCHMARK_COMMANDLINEFLAGS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Macro for referencing flags. 8 | #define FLAG(name) FLAGS_##name 9 | 10 | // Macros for declaring flags. 11 | #define DECLARE_bool(name) extern bool FLAG(name) 12 | #define DECLARE_int32(name) extern int32_t FLAG(name) 13 | #define DECLARE_int64(name) extern int64_t FLAG(name) 14 | #define DECLARE_double(name) extern double FLAG(name) 15 | #define DECLARE_string(name) extern std::string FLAG(name) 16 | 17 | // Macros for defining flags. 18 | #define DEFINE_bool(name, default_val, doc) bool FLAG(name) = (default_val) 19 | #define DEFINE_int32(name, default_val, doc) int32_t FLAG(name) = (default_val) 20 | #define DEFINE_int64(name, default_val, doc) int64_t FLAG(name) = (default_val) 21 | #define DEFINE_double(name, default_val, doc) double FLAG(name) = (default_val) 22 | #define DEFINE_string(name, default_val, doc) \ 23 | std::string FLAG(name) = (default_val) 24 | 25 | namespace benchmark { 26 | // Parses 'str' for a 32-bit signed integer. If successful, writes the result 27 | // to *value and returns true; otherwise leaves *value unchanged and returns 28 | // false. 29 | bool ParseInt32(const std::string& src_text, const char* str, int32_t* value); 30 | 31 | // Parses a bool/Int32/string from the environment variable 32 | // corresponding to the given Google Test flag. 33 | bool BoolFromEnv(const char* flag, bool default_val); 34 | int32_t Int32FromEnv(const char* flag, int32_t default_val); 35 | double DoubleFromEnv(const char* flag, double default_val); 36 | const char* StringFromEnv(const char* flag, const char* default_val); 37 | 38 | // Parses a string for a bool flag, in the form of either 39 | // "--flag=value" or "--flag". 40 | // 41 | // In the former case, the value is taken as true as long as it does 42 | // not start with '0', 'f', or 'F'. 43 | // 44 | // In the latter case, the value is taken as true. 45 | // 46 | // On success, stores the value of the flag in *value, and returns 47 | // true. On failure, returns false without changing *value. 48 | bool ParseBoolFlag(const char* str, const char* flag, bool* value); 49 | 50 | // Parses a string for an Int32 flag, in the form of 51 | // "--flag=value". 52 | // 53 | // On success, stores the value of the flag in *value, and returns 54 | // true. On failure, returns false without changing *value. 55 | bool ParseInt32Flag(const char* str, const char* flag, int32_t* value); 56 | 57 | // Parses a string for a Double flag, in the form of 58 | // "--flag=value". 59 | // 60 | // On success, stores the value of the flag in *value, and returns 61 | // true. On failure, returns false without changing *value. 62 | bool ParseDoubleFlag(const char* str, const char* flag, double* value); 63 | 64 | // Parses a string for a string flag, in the form of 65 | // "--flag=value". 66 | // 67 | // On success, stores the value of the flag in *value, and returns 68 | // true. On failure, returns false without changing *value. 69 | bool ParseStringFlag(const char* str, const char* flag, std::string* value); 70 | 71 | // Returns true if the string matches the flag. 72 | bool IsFlag(const char* str, const char* flag); 73 | 74 | } // end namespace benchmark 75 | 76 | #endif // BENCHMARK_COMMANDLINEFLAGS_H_ 77 | -------------------------------------------------------------------------------- /src/metafast/metafast_type_traits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util/stl_container_forward.hpp" 4 | 5 | namespace metaf 6 | { 7 | 8 | namespace detail 9 | { 10 | template 11 | struct equality_comparable_helper 12 | { 13 | static constexpr bool value = false; 14 | }; 15 | 16 | template 17 | struct equality_comparable_helper(std::declval() == std::declval()))>::type> 18 | { 19 | static constexpr bool value = true; 20 | }; 21 | } 22 | 23 | template 24 | struct is_equality_comparable 25 | : detail::equality_comparable_helper 26 | { 27 | }; 28 | template 29 | struct is_equality_comparable 30 | : metaf::is_equality_comparable 31 | { 32 | }; 33 | template 34 | struct is_equality_comparable> 35 | : metaf::is_equality_comparable 36 | { 37 | }; 38 | template 39 | struct is_equality_comparable> 40 | : metaf::is_equality_comparable 41 | { 42 | }; 43 | template 44 | struct is_equality_comparable> 45 | : metaf::is_equality_comparable 46 | { 47 | }; 48 | template 49 | struct is_equality_comparable> 50 | : metaf::is_equality_comparable 51 | { 52 | }; 53 | template 54 | struct is_equality_comparable> 55 | : metaf::is_equality_comparable 56 | { 57 | }; 58 | 59 | template 60 | struct is_equality_comparable> 61 | { 62 | static constexpr bool value = metaf::is_equality_comparable::value 63 | && metaf::is_equality_comparable::value; 64 | }; 65 | template 66 | struct is_equality_comparable> 67 | { 68 | static constexpr bool value = metaf::is_equality_comparable::value 69 | && metaf::is_equality_comparable::value; 70 | }; 71 | template 72 | struct is_equality_comparable> 73 | : metaf::is_equality_comparable 74 | { 75 | }; 76 | template 77 | struct is_equality_comparable> 78 | : metaf::is_equality_comparable 79 | { 80 | }; 81 | 82 | template 83 | struct is_equality_comparable> 84 | { 85 | static constexpr bool value = metaf::is_equality_comparable::value 86 | && metaf::is_equality_comparable::value; 87 | }; 88 | template 89 | struct is_equality_comparable> 90 | { 91 | static constexpr bool value = metaf::is_equality_comparable::value 92 | && metaf::is_equality_comparable::value; 93 | }; 94 | template 95 | struct is_equality_comparable> 96 | : metaf::is_equality_comparable 97 | { 98 | }; 99 | template 100 | struct is_equality_comparable> 101 | : metaf::is_equality_comparable 102 | { 103 | }; 104 | 105 | } 106 | -------------------------------------------------------------------------------- /libs/benchmark/src/reporter.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "benchmark/reporter.h" 16 | 17 | #include 18 | #include 19 | 20 | #include "check.h" 21 | #include "stat.h" 22 | 23 | namespace benchmark { 24 | 25 | void BenchmarkReporter::ComputeStats( 26 | const std::vector& reports, 27 | Run* mean_data, Run* stddev_data) { 28 | CHECK(reports.size() >= 2) << "Cannot compute stats for less than 2 reports"; 29 | // Accumulators. 30 | Stat1_d real_accumulated_time_stat; 31 | Stat1_d cpu_accumulated_time_stat; 32 | Stat1_d bytes_per_second_stat; 33 | Stat1_d items_per_second_stat; 34 | // All repetitions should be run with the same number of iterations so we 35 | // can take this information from the first benchmark. 36 | int64_t const run_iterations = reports.front().iterations; 37 | 38 | // Populate the accumulators. 39 | for (Run const& run : reports) { 40 | CHECK_EQ(reports[0].benchmark_name, run.benchmark_name); 41 | CHECK_EQ(run_iterations, run.iterations); 42 | real_accumulated_time_stat += 43 | Stat1_d(run.real_accumulated_time/run.iterations, run.iterations); 44 | cpu_accumulated_time_stat += 45 | Stat1_d(run.cpu_accumulated_time/run.iterations, run.iterations); 46 | items_per_second_stat += Stat1_d(run.items_per_second, run.iterations); 47 | bytes_per_second_stat += Stat1_d(run.bytes_per_second, run.iterations); 48 | } 49 | 50 | // Get the data from the accumulator to BenchmarkReporter::Run's. 51 | mean_data->benchmark_name = reports[0].benchmark_name + "_mean"; 52 | mean_data->iterations = run_iterations; 53 | mean_data->real_accumulated_time = real_accumulated_time_stat.Mean() * 54 | run_iterations; 55 | mean_data->cpu_accumulated_time = cpu_accumulated_time_stat.Mean() * 56 | run_iterations; 57 | mean_data->bytes_per_second = bytes_per_second_stat.Mean(); 58 | mean_data->items_per_second = items_per_second_stat.Mean(); 59 | 60 | // Only add label to mean/stddev if it is same for all runs 61 | mean_data->report_label = reports[0].report_label; 62 | for (std::size_t i = 1; i < reports.size(); i++) { 63 | if (reports[i].report_label != reports[0].report_label) { 64 | mean_data->report_label = ""; 65 | break; 66 | } 67 | } 68 | 69 | stddev_data->benchmark_name = reports[0].benchmark_name + "_stddev"; 70 | stddev_data->report_label = mean_data->report_label; 71 | stddev_data->iterations = 0; 72 | stddev_data->real_accumulated_time = 73 | real_accumulated_time_stat.StdDev(); 74 | stddev_data->cpu_accumulated_time = 75 | cpu_accumulated_time_stat.StdDev(); 76 | stddev_data->bytes_per_second = bytes_per_second_stat.StdDev(); 77 | stddev_data->items_per_second = items_per_second_stat.StdDev(); 78 | } 79 | 80 | void BenchmarkReporter::Finalize() { 81 | } 82 | 83 | BenchmarkReporter::~BenchmarkReporter() { 84 | } 85 | 86 | } // end namespace benchmark 87 | -------------------------------------------------------------------------------- /src/metav3/serialization/serialization_test.cpp: -------------------------------------------------------------------------------- 1 | #include "metav3/serialization/serialization_test.hpp" 2 | 3 | #ifndef DISABLE_GTEST 4 | #include "metafast/metafast.hpp" 5 | 6 | REFLECT_CLASS_START(srlztest::base_struct_a, 0) 7 | REFLECT_MEMBER(a); 8 | REFLECT_CLASS_END() 9 | 10 | REFLECT_CLASS_START(srlztest::base_struct_b, 0) 11 | REFLECT_MEMBER(b); 12 | REFLECT_CLASS_END() 13 | 14 | REFLECT_CLASS_START(srlztest::derived_struct, 0) 15 | REFLECT_BASE(srlztest::base_struct_a); 16 | REFLECT_BASE(srlztest::base_struct_b); 17 | REFLECT_MEMBER(c); 18 | REFLECT_CLASS_END() 19 | 20 | REFLECT_ABSTRACT_CLASS_START(srlztest::base_struct_d, 0) 21 | REFLECT_MEMBER(d); 22 | REFLECT_CLASS_END() 23 | 24 | REFLECT_CLASS_START(srlztest::derived_derived, 0) 25 | REFLECT_BASE(srlztest::base_struct_d); 26 | REFLECT_BASE(srlztest::derived_struct); 27 | REFLECT_MEMBER(e); 28 | REFLECT_CLASS_END() 29 | 30 | REFLECT_ABSTRACT_CLASS_START(srlztest::pointer_to_struct_base, 0) 31 | REFLECT_MEMBER(a); 32 | REFLECT_CLASS_END() 33 | 34 | REFLECT_ABSTRACT_CLASS_START(srlztest::pointer_to_struct_offsetting_base, 0) 35 | REFLECT_MEMBER(c); 36 | REFLECT_CLASS_END() 37 | 38 | REFLECT_CLASS_START(srlztest::pointer_to_struct_derived, 0) 39 | REFLECT_BASE(srlztest::pointer_to_struct_offsetting_base); 40 | REFLECT_BASE(srlztest::pointer_to_struct_base); 41 | REFLECT_MEMBER(b); 42 | REFLECT_CLASS_END() 43 | 44 | REFLECT_CLASS_START(srlztest::pointer_member, 0) 45 | REFLECT_MEMBER(ptr); 46 | REFLECT_CLASS_END() 47 | 48 | namespace metav3 49 | { 50 | #ifdef META_SUPPORTS_CONDITIONAL_MEMBER 51 | static bool conditional_member_b_condition(const srlztest::conditional_member & object) 52 | { 53 | return !object.which; 54 | } 55 | static MetaType::StructInfo::MemberCollection get_conditional_member_members(int8_t) 56 | { 57 | return 58 | { 59 | { 60 | MetaMember("which", &srlztest::conditional_member::which) 61 | }, 62 | { 63 | MetaConditionalMember::CreateFromMember(MetaMember("a", &srlztest::conditional_member::a)), 64 | MetaConditionalMember::CreateFromFunction(MetaMember("b", &srlztest::conditional_member::b)) 65 | } 66 | }; 67 | } 68 | template<> 69 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterStruct("srlz_conditional_member", 0, &get_conditional_member_members); 70 | #endif 71 | #ifdef META_SUPPORTS_TYPE_ERASURE 72 | static MetaType::StructInfo::MemberCollection get_type_erasure_member_members(int8_t) 73 | { 74 | return 75 | { 76 | { 77 | MetaMember("a", &srlztest::type_erasure_member::a) 78 | }, 79 | {} 80 | }; 81 | } 82 | template<> 83 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterTypeErasure(); 84 | template<> 85 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterStruct("srlz_type_erasure", 0, &get_type_erasure_member_members); 86 | static MetaType::TypeErasureInfo::SupportedType support_type_erasure; 87 | #endif 88 | 89 | template<> 90 | const MetaType MetaType::MetaTypeConstructor::type = MetaType::RegisterEnum({ { srlztest::EnumValueOne, "EnumValueOne" }, { srlztest::EnumValueTwo, "EnumValueTwo" } }); 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /src/meta/serialization/new_meta_compile_test.cpp: -------------------------------------------------------------------------------- 1 | #ifndef DISABLE_GTEST 2 | #include 3 | #include "debug/profile.hpp" 4 | //#define TEST_COMPILE_TIME_NEW_META 5 | #ifdef TEST_COMPILE_TIME_NEW_META 6 | #include "Meta/newMeta.hpp" 7 | #include "Meta/Serialization/json.hpp" 8 | #include "Meta/Serialization/simpleBinary.hpp" 9 | 10 | using namespace meta; 11 | 12 | template 13 | struct TestStruct : TestStruct 14 | { 15 | TestStruct(int j = 0) 16 | : TestStruct(j), int_member(i + j), struct_member(j) 17 | { 18 | } 19 | 20 | int int_member; 21 | 22 | TestStruct & GetStructMember() 23 | { 24 | return struct_member; 25 | } 26 | 27 | bool operator==(const TestStruct & other) const 28 | { 29 | return int_member == other.int_member && struct_member == other.struct_member && TestStruct::operator==(other); 30 | } 31 | 32 | private: 33 | TestStruct struct_member; 34 | }; 35 | 36 | template<> 37 | struct TestStruct<0> 38 | { 39 | TestStruct(int = 0) 40 | : last_member(0.5f) 41 | { 42 | } 43 | 44 | bool operator==(const TestStruct & other) const 45 | { 46 | return last_member == other.last_member; 47 | } 48 | 49 | float last_member; 50 | }; 51 | 52 | template 53 | static MetaType::StructInfo::MemberCollection get_test_struct_members(int16_t) 54 | { 55 | return 56 | { 57 | { 58 | MetaMember::CreateFromMemPtr, &TestStruct::int_member>("int_member_" + std::to_string(i)), 59 | MetaMember::CreateFromGetRef, TestStruct, &TestStruct::GetStructMember>("struct_member_" + std::to_string(i)) 60 | }, 61 | { 62 | } 63 | }; 64 | } 65 | template<> 66 | MetaType::StructInfo::MemberCollection get_test_struct_members<0>(int16_t) 67 | { 68 | return 69 | { 70 | { 71 | MetaMember::CreateFromMemPtr, &TestStruct<0>::last_member>("last_member") 72 | }, 73 | { 74 | } 75 | }; 76 | } 77 | 78 | template 79 | static MetaType::StructInfo::BaseClassCollection get_test_struct_bases(int16_t) 80 | { 81 | return 82 | { 83 | { 84 | MetaBaseClass::Create, TestStruct >() 85 | } 86 | }; 87 | } 88 | template<> 89 | MetaType::StructInfo::BaseClassCollection get_test_struct_bases<0>(int16_t) 90 | { 91 | return { { } }; 92 | } 93 | 94 | namespace meta 95 | { 96 | template 97 | struct MetaType::MetaTypeConstructor > 98 | { 99 | static const MetaType type; 100 | }; 101 | template 102 | const MetaType MetaType::MetaTypeConstructor >::type = MetaType::RegisterStruct >("TestStruct_" + std::to_string(i), 0, &get_test_struct_members, &get_test_struct_bases); 103 | } 104 | 105 | #include 106 | 107 | TEST(new_meta, TestCompileTime) 108 | { 109 | typedef TestStruct<128> ChosenStruct; 110 | std::unique_ptr original(new ChosenStruct(5)); 111 | std::unique_ptr copy; 112 | #define USE_BINARY 113 | #ifdef USE_BINARY 114 | std::stringstream out; 115 | { 116 | ScopedMeasurer write("write"); 117 | write_binary(ConstMetaReference(original), out); 118 | } 119 | std::cout << out.str().size() << std::endl; 120 | MetaReference as_reference(copy); 121 | { 122 | ScopedMeasurer read("read"); 123 | read_binary(as_reference, out); 124 | } 125 | #else 126 | std::string as_json = to_json(ConstMetaReference(original)); 127 | MetaReference as_reference(copy); 128 | from_json(as_reference, as_json); 129 | #endif 130 | ASSERT_TRUE(bool(copy)); 131 | ASSERT_EQ(*original, *copy); 132 | } 133 | 134 | #endif 135 | #endif 136 | -------------------------------------------------------------------------------- /libs/benchmark/src/colorprint.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "colorprint.h" 16 | 17 | #include 18 | 19 | #include "commandlineflags.h" 20 | #include "internal_macros.h" 21 | 22 | #ifdef BENCHMARK_OS_WINDOWS 23 | #include 24 | #endif 25 | 26 | DECLARE_bool(color_print); 27 | 28 | namespace benchmark { 29 | namespace { 30 | #ifdef BENCHMARK_OS_WINDOWS 31 | typedef WORD PlatformColorCode; 32 | #else 33 | typedef const char* PlatformColorCode; 34 | #endif 35 | 36 | PlatformColorCode GetPlatformColorCode(LogColor color) { 37 | #ifdef BENCHMARK_OS_WINDOWS 38 | switch (color) { 39 | case COLOR_RED: 40 | return FOREGROUND_RED; 41 | case COLOR_GREEN: 42 | return FOREGROUND_GREEN; 43 | case COLOR_YELLOW: 44 | return FOREGROUND_RED | FOREGROUND_GREEN; 45 | case COLOR_BLUE: 46 | return FOREGROUND_BLUE; 47 | case COLOR_MAGENTA: 48 | return FOREGROUND_BLUE | FOREGROUND_RED; 49 | case COLOR_CYAN: 50 | return FOREGROUND_BLUE | FOREGROUND_GREEN; 51 | case COLOR_WHITE: // fall through to default 52 | default: 53 | return 0; 54 | } 55 | #else 56 | switch (color) { 57 | case COLOR_RED: 58 | return "1"; 59 | case COLOR_GREEN: 60 | return "2"; 61 | case COLOR_YELLOW: 62 | return "3"; 63 | case COLOR_BLUE: 64 | return "4"; 65 | case COLOR_MAGENTA: 66 | return "5"; 67 | case COLOR_CYAN: 68 | return "6"; 69 | case COLOR_WHITE: 70 | return "7"; 71 | default: 72 | return nullptr; 73 | }; 74 | #endif 75 | } 76 | } // end namespace 77 | 78 | void ColorPrintf(LogColor color, const char* fmt, ...) { 79 | va_list args; 80 | va_start(args, fmt); 81 | 82 | if (!FLAGS_color_print) { 83 | vprintf(fmt, args); 84 | va_end(args); 85 | return; 86 | } 87 | 88 | #ifdef BENCHMARK_OS_WINDOWS 89 | const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); 90 | 91 | // Gets the current text color. 92 | CONSOLE_SCREEN_BUFFER_INFO buffer_info; 93 | GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); 94 | const WORD old_color_attrs = buffer_info.wAttributes; 95 | 96 | // We need to flush the stream buffers into the console before each 97 | // SetConsoleTextAttribute call lest it affect the text that is already 98 | // printed but has not yet reached the console. 99 | fflush(stdout); 100 | SetConsoleTextAttribute(stdout_handle, 101 | GetPlatformColorCode(color) | FOREGROUND_INTENSITY); 102 | vprintf(fmt, args); 103 | 104 | fflush(stdout); 105 | // Restores the text color. 106 | SetConsoleTextAttribute(stdout_handle, old_color_attrs); 107 | #else 108 | const char* color_code = GetPlatformColorCode(color); 109 | if (color_code) fprintf(stdout, "\033[0;3%sm", color_code); 110 | vprintf(fmt, args); 111 | printf("\033[m"); // Resets the terminal to default. 112 | #endif 113 | va_end(args); 114 | } 115 | } // end namespace benchmark 116 | -------------------------------------------------------------------------------- /libs/benchmark/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Enable the tests 2 | 3 | find_package(Threads REQUIRED) 4 | 5 | set(CXX03_FLAGS "${CMAKE_CXX_FLAGS}") 6 | string(REPLACE "-std=c++11" "-std=c++03" CXX03_FLAGS "${CXX03_FLAGS}") 7 | string(REPLACE "-std=c++0x" "-std=c++03" CXX03_FLAGS "${CXX03_FLAGS}") 8 | 9 | macro(compile_benchmark_test name) 10 | add_executable(${name} "${name}.cc") 11 | target_link_libraries(${name} benchmark ${CMAKE_THREAD_LIBS_INIT}) 12 | endmacro(compile_benchmark_test) 13 | 14 | # Demonstration executable 15 | compile_benchmark_test(benchmark_test) 16 | add_test(benchmark benchmark_test --benchmark_min_time=0.01) 17 | 18 | compile_benchmark_test(filter_test) 19 | macro(add_filter_test name filter expect) 20 | add_test(${name} filter_test --benchmark_min_time=0.01 --benchmark_filter=${filter} ${expect}) 21 | endmacro(add_filter_test) 22 | 23 | add_filter_test(filter_simple "Foo" 3) 24 | add_filter_test(filter_suffix "BM_.*" 4) 25 | add_filter_test(filter_regex_all ".*" 5) 26 | add_filter_test(filter_regex_blank "" 5) 27 | add_filter_test(filter_regex_none "monkey" 0) 28 | add_filter_test(filter_regex_wildcard ".*Foo.*" 3) 29 | add_filter_test(filter_regex_begin "^BM_.*" 4) 30 | add_filter_test(filter_regex_begin2 "^N" 1) 31 | add_filter_test(filter_regex_end ".*Ba$" 1) 32 | 33 | compile_benchmark_test(options_test) 34 | add_test(options_benchmarks options_test --benchmark_min_time=0.01) 35 | 36 | compile_benchmark_test(basic_test) 37 | add_test(basic_benchmark basic_test --benchmark_min_time=0.01) 38 | 39 | compile_benchmark_test(fixture_test) 40 | add_test(fixture_test fixture_test --benchmark_min_time=0.01) 41 | 42 | compile_benchmark_test(cxx03_test) 43 | set_target_properties(cxx03_test 44 | PROPERTIES COMPILE_FLAGS "${CXX03_FLAGS}") 45 | add_test(cxx03 cxx03_test --benchmark_min_time=0.01) 46 | 47 | # Add the coverage command(s) 48 | if(CMAKE_BUILD_TYPE) 49 | string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) 50 | endif() 51 | if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage") 52 | find_program(GCOV gcov) 53 | find_program(LCOV lcov) 54 | find_program(GENHTML genhtml) 55 | find_program(CTEST ctest) 56 | if (GCOV AND LCOV AND GENHTML AND CTEST AND HAVE_CXX_FLAG_COVERAGE) 57 | add_custom_command( 58 | OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html 59 | COMMAND ${LCOV} -q -z -d . 60 | COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i 61 | COMMAND ${CTEST} --force-new-ctest-process 62 | COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov 63 | COMMAND ${LCOV} -q -a before.lcov -a after.lcov --output-file final.lcov 64 | COMMAND ${LCOV} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov 65 | COMMAND ${GENHTML} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_BINARY_DIR}" -t benchmark 66 | DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test 67 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 68 | COMMENT "Running LCOV" 69 | ) 70 | add_custom_target(coverage 71 | DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html 72 | COMMENT "LCOV report at lcov/index.html" 73 | ) 74 | message(STATUS "Coverage command added") 75 | else() 76 | if (HAVE_CXX_FLAG_COVERAGE) 77 | set(CXX_FLAG_COVERAGE_MESSAGE supported) 78 | else() 79 | set(CXX_FLAG_COVERAGE_MESSAGE unavailable) 80 | endif() 81 | message(WARNING 82 | "Coverage not available:\n" 83 | " gcov: ${GCOV}\n" 84 | " lcov: ${LCOV}\n" 85 | " genhtml: ${GENHTML}\n" 86 | " ctest: ${CTEST}\n" 87 | " --coverage flag: ${CXX_FLAG_COVERAGE_MESSAGE}") 88 | endif() 89 | endif() 90 | -------------------------------------------------------------------------------- /libs/benchmark/src/csv_reporter.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "benchmark/reporter.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "string_util.h" 23 | #include "walltime.h" 24 | 25 | // File format reference: http://edoceo.com/utilitas/csv-file-format. 26 | 27 | namespace benchmark { 28 | 29 | bool CSVReporter::ReportContext(const Context& context) { 30 | std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu 31 | << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n"; 32 | 33 | std::cerr << LocalDateTimeString() << "\n"; 34 | 35 | if (context.cpu_scaling_enabled) { 36 | std::cerr << "***WARNING*** CPU scaling is enabled, the benchmark " 37 | "real time measurements may be noisy and will incure extra " 38 | "overhead.\n"; 39 | } 40 | 41 | #ifndef NDEBUG 42 | std::cerr << "***WARNING*** Library was built as DEBUG. Timings may be " 43 | "affected.\n"; 44 | #endif 45 | std::cout << "name,iterations,real_time,cpu_time,bytes_per_second," 46 | "items_per_second,label\n"; 47 | return true; 48 | } 49 | 50 | void CSVReporter::ReportRuns(std::vector const& reports) { 51 | if (reports.empty()) { 52 | return; 53 | } 54 | 55 | std::vector reports_cp = reports; 56 | if (reports.size() >= 2) { 57 | Run mean_data; 58 | Run stddev_data; 59 | BenchmarkReporter::ComputeStats(reports, &mean_data, &stddev_data); 60 | reports_cp.push_back(mean_data); 61 | reports_cp.push_back(stddev_data); 62 | } 63 | for (auto it = reports_cp.begin(); it != reports_cp.end(); ++it) { 64 | PrintRunData(*it); 65 | } 66 | } 67 | 68 | void CSVReporter::PrintRunData(Run const& run) { 69 | double const multiplier = 1e9; // nano second multiplier 70 | double cpu_time = run.cpu_accumulated_time * multiplier; 71 | double real_time = run.real_accumulated_time * multiplier; 72 | if (run.iterations != 0) { 73 | real_time = real_time / static_cast(run.iterations); 74 | cpu_time = cpu_time / static_cast(run.iterations); 75 | } 76 | 77 | // Field with embedded double-quote characters must be doubled and the field 78 | // delimited with double-quotes. 79 | std::string name = run.benchmark_name; 80 | ReplaceAll(&name, "\"", "\"\""); 81 | std::cout << "\"" << name << "\","; 82 | 83 | std::cout << run.iterations << ","; 84 | std::cout << real_time << ","; 85 | std::cout << cpu_time << ","; 86 | 87 | if (run.bytes_per_second > 0.0) { 88 | std::cout << run.bytes_per_second; 89 | } 90 | std::cout << ","; 91 | if (run.items_per_second > 0.0) { 92 | std::cout << run.items_per_second; 93 | } 94 | std::cout << ","; 95 | if (!run.report_label.empty()) { 96 | // Field with embedded double-quote characters must be doubled and the field 97 | // delimited with double-quotes. 98 | std::string label = run.report_label; 99 | ReplaceAll(&label, "\"", "\"\""); 100 | std::cout << "\"" << label << "\""; 101 | } 102 | std::cout << '\n'; 103 | } 104 | 105 | } // end namespace benchmark 106 | -------------------------------------------------------------------------------- /libs/benchmark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8.11) 2 | project (benchmark) 3 | 4 | option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON) 5 | option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF) 6 | # Make sure we can import out CMake functions 7 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 8 | 9 | # Read the git tags to determine the project version 10 | include(GetGitVersion) 11 | get_git_version(GIT_VERSION) 12 | 13 | # Tell the user what versions we are using 14 | string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${GIT_VERSION}) 15 | message("-- Version: ${VERSION}") 16 | 17 | # The version of the libraries 18 | set(GENERIC_LIB_VERSION ${VERSION}) 19 | string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION) 20 | 21 | # Import our CMake modules 22 | include(CheckCXXCompilerFlag) 23 | include(AddCXXCompilerFlag) 24 | include(CXXFeatureCheck) 25 | 26 | # Try and enable C++11. Don't use C++14 because it doesn't work in some 27 | # configurations. 28 | add_cxx_compiler_flag(-std=c++11) 29 | if (NOT HAVE_CXX_FLAG_STD_CXX11) 30 | add_cxx_compiler_flag(-std=c++0x) 31 | endif() 32 | 33 | # Turn compiler warnings up to 11 34 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 35 | add_cxx_compiler_flag(-W4) 36 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 37 | else() 38 | add_cxx_compiler_flag(-Wall) 39 | endif() 40 | add_cxx_compiler_flag(-Wextra) 41 | add_cxx_compiler_flag(-Wshadow) 42 | add_cxx_compiler_flag(-Werror RELEASE) 43 | add_cxx_compiler_flag(-pedantic) 44 | add_cxx_compiler_flag(-pedantic-errors) 45 | add_cxx_compiler_flag(-Wshorten-64-to-32) 46 | add_cxx_compiler_flag(-Wfloat-equal) 47 | add_cxx_compiler_flag(-Wzero-as-null-pointer-constant) 48 | add_cxx_compiler_flag(-fstrict-aliasing) 49 | if (HAVE_CXX_FLAG_FSTRICT_ALIASING) 50 | add_cxx_compiler_flag(-Wstrict-aliasing) 51 | endif() 52 | add_cxx_compiler_flag(-Wthread-safety) 53 | if (HAVE_WTHREAD_SAFETY) 54 | add_definitions(-DHAVE_WTHREAD_SAFETY) 55 | cxx_feature_check(THREAD_SAFETY_ATTRIBUTES) 56 | endif() 57 | 58 | # Link time optimisation 59 | if (BENCHMARK_ENABLE_LTO) 60 | add_cxx_compiler_flag(-flto) 61 | if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") 62 | find_program(GCC_AR gcc-ar) 63 | if (GCC_AR) 64 | set(CMAKE_AR ${GCC_AR}) 65 | endif() 66 | find_program(GCC_RANLIB gcc-ranlib) 67 | if (GCC_RANLIB) 68 | set(CMAKE_RANLIB ${GCC_RANLIB}) 69 | endif() 70 | endif() 71 | endif() 72 | 73 | # Coverage build type 74 | set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING 75 | "Flags used by the C++ compiler during coverage builds." 76 | FORCE) 77 | set(CMAKE_EXE_LINKER_FLAGS_COVERAGE 78 | "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING 79 | "Flags used for linking binaries during coverage builds." 80 | FORCE) 81 | set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE 82 | "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING 83 | "Flags used by the shared libraries linker during coverage builds." 84 | FORCE) 85 | mark_as_advanced( 86 | CMAKE_CXX_FLAGS_COVERAGE 87 | CMAKE_EXE_LINKER_FLAGS_COVERAGE 88 | CMAKE_SHARED_LINKER_FLAGS_COVERAGE) 89 | set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING 90 | "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage." 91 | FORCE) 92 | add_cxx_compiler_flag(--coverage COVERAGE) 93 | 94 | # C++ feature checks 95 | cxx_feature_check(STD_REGEX) 96 | cxx_feature_check(GNU_POSIX_REGEX) 97 | cxx_feature_check(POSIX_REGEX) 98 | cxx_feature_check(STEADY_CLOCK) 99 | 100 | # Ensure we have pthreads 101 | find_package(Threads REQUIRED) 102 | 103 | # Set up directories 104 | include_directories(${PROJECT_SOURCE_DIR}/include) 105 | 106 | # Build the targets 107 | add_subdirectory(src) 108 | 109 | if (BENCHMARK_ENABLE_TESTING) 110 | enable_testing() 111 | add_subdirectory(test) 112 | endif() 113 | -------------------------------------------------------------------------------- /src/util/memoizingMap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "util/copyableMutex.hpp" 5 | 6 | 7 | template 8 | struct lazy_initialize 9 | { 10 | lazy_initialize() 11 | { 12 | } 13 | lazy_initialize(const lazy_initialize & other) 14 | { 15 | if (other.initialized) 16 | { 17 | std::call_once(once, [&] 18 | { 19 | new (std::addressof(value)) T(other.value); 20 | initialized = true; 21 | }); 22 | } 23 | } 24 | lazy_initialize & operator=(const lazy_initialize & other) 25 | { 26 | if (initialized) 27 | { 28 | if (other.initialized) 29 | { 30 | value = other.value; 31 | } 32 | else 33 | { 34 | once.~once_flag(); 35 | new (&once) std::once_flag(); 36 | value.~T(); 37 | initialized = false; 38 | } 39 | } 40 | else if (other.initialized) 41 | { 42 | std::call_once(once, [&] 43 | { 44 | new (std::addressof(value)) T(other.value); 45 | initialized = true; 46 | }); 47 | } 48 | } 49 | lazy_initialize(lazy_initialize && other) 50 | { 51 | if (other.initialized) 52 | { 53 | std::call_once(once, [&] 54 | { 55 | new (std::addressof(value)) T(std::move(other.value)); 56 | initialized = true; 57 | }); 58 | } 59 | } 60 | lazy_initialize & operator=(lazy_initialize && other) 61 | { 62 | if (initialized) 63 | { 64 | if (other.initialized) 65 | { 66 | value = std::move(other.value); 67 | } 68 | else 69 | { 70 | once.~once_flag(); 71 | new (&once) std::once_flag(); 72 | value.~T(); 73 | initialized = false; 74 | } 75 | } 76 | else if (other.initialized) 77 | { 78 | std::call_once(once, [&] 79 | { 80 | new (std::addressof(value)) T(std::move(other.value)); 81 | initialized = true; 82 | }); 83 | } 84 | return *this; 85 | } 86 | ~lazy_initialize() 87 | { 88 | if (initialized) 89 | value.~T(); 90 | } 91 | 92 | template 93 | const T & get(Func && initializer) const 94 | { 95 | return const_cast(*this).get(std::forward(initializer)); 96 | } 97 | template 98 | T & get(Func && initializer) 99 | { 100 | std::call_once(once, [&] 101 | { 102 | new (std::addressof(value)) T(initializer()); 103 | initialized = true; 104 | }); 105 | return value; 106 | } 107 | 108 | private: 109 | mutable std::once_flag once; 110 | mutable bool initialized = false; 111 | union { T value; }; 112 | }; 113 | 114 | template, typename Allocator = std::allocator > > 115 | struct memoizing_map 116 | { 117 | template 118 | V & get(const K & key, const DefaultFunc & func) 119 | { 120 | return const_cast(const_cast(*this).get(key, func)); 121 | } 122 | template 123 | const V & get(const K & key, const DefaultFunc & func) const 124 | { 125 | return [&]() -> const lazy_initialize & 126 | { 127 | std::lock_guard lock(map_mutex); 128 | return map[key]; 129 | }().get([&]() -> decltype(auto) 130 | { 131 | return func(key); 132 | }); 133 | } 134 | 135 | private: 136 | mutable copyable_mutex map_mutex; 137 | mutable std::map, Comp, Allocator> map; 138 | }; 139 | -------------------------------------------------------------------------------- /libs/benchmark/.ycm_extra_conf.py: -------------------------------------------------------------------------------- 1 | import os 2 | import ycm_core 3 | 4 | # These are the compilation flags that will be used in case there's no 5 | # compilation database set (by default, one is not set). 6 | # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. 7 | flags = [ 8 | '-Wall', 9 | '-Werror', 10 | '-pendantic-errors', 11 | '-std=c++0x', 12 | '-fno-strict-aliasing', 13 | '-O3', 14 | '-DNDEBUG', 15 | # ...and the same thing goes for the magic -x option which specifies the 16 | # language that the files to be compiled are written in. This is mostly 17 | # relevant for c++ headers. 18 | # For a C project, you would set this to 'c' instead of 'c++'. 19 | '-x', 'c++', 20 | '-I', 'include', 21 | '-isystem', '/usr/include', 22 | '-isystem', '/usr/local/include', 23 | ] 24 | 25 | 26 | # Set this to the absolute path to the folder (NOT the file!) containing the 27 | # compile_commands.json file to use that instead of 'flags'. See here for 28 | # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html 29 | # 30 | # Most projects will NOT need to set this to anything; you can just change the 31 | # 'flags' list of compilation flags. Notice that YCM itself uses that approach. 32 | compilation_database_folder = '' 33 | 34 | if os.path.exists( compilation_database_folder ): 35 | database = ycm_core.CompilationDatabase( compilation_database_folder ) 36 | else: 37 | database = None 38 | 39 | SOURCE_EXTENSIONS = [ '.cc' ] 40 | 41 | def DirectoryOfThisScript(): 42 | return os.path.dirname( os.path.abspath( __file__ ) ) 43 | 44 | 45 | def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): 46 | if not working_directory: 47 | return list( flags ) 48 | new_flags = [] 49 | make_next_absolute = False 50 | path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] 51 | for flag in flags: 52 | new_flag = flag 53 | 54 | if make_next_absolute: 55 | make_next_absolute = False 56 | if not flag.startswith( '/' ): 57 | new_flag = os.path.join( working_directory, flag ) 58 | 59 | for path_flag in path_flags: 60 | if flag == path_flag: 61 | make_next_absolute = True 62 | break 63 | 64 | if flag.startswith( path_flag ): 65 | path = flag[ len( path_flag ): ] 66 | new_flag = path_flag + os.path.join( working_directory, path ) 67 | break 68 | 69 | if new_flag: 70 | new_flags.append( new_flag ) 71 | return new_flags 72 | 73 | 74 | def IsHeaderFile( filename ): 75 | extension = os.path.splitext( filename )[ 1 ] 76 | return extension in [ '.h', '.hxx', '.hpp', '.hh' ] 77 | 78 | 79 | def GetCompilationInfoForFile( filename ): 80 | # The compilation_commands.json file generated by CMake does not have entries 81 | # for header files. So we do our best by asking the db for flags for a 82 | # corresponding source file, if any. If one exists, the flags for that file 83 | # should be good enough. 84 | if IsHeaderFile( filename ): 85 | basename = os.path.splitext( filename )[ 0 ] 86 | for extension in SOURCE_EXTENSIONS: 87 | replacement_file = basename + extension 88 | if os.path.exists( replacement_file ): 89 | compilation_info = database.GetCompilationInfoForFile( 90 | replacement_file ) 91 | if compilation_info.compiler_flags_: 92 | return compilation_info 93 | return None 94 | return database.GetCompilationInfoForFile( filename ) 95 | 96 | 97 | def FlagsForFile( filename, **kwargs ): 98 | if database: 99 | # Bear in mind that compilation_info.compiler_flags_ does NOT return a 100 | # python list, but a "list-like" StringVec object 101 | compilation_info = GetCompilationInfoForFile( filename ) 102 | if not compilation_info: 103 | return None 104 | 105 | final_flags = MakeRelativePathsInFlagsAbsolute( 106 | compilation_info.compiler_flags_, 107 | compilation_info.compiler_working_dir_ ) 108 | else: 109 | relative_to = DirectoryOfThisScript() 110 | final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) 111 | 112 | return { 113 | 'flags': final_flags, 114 | 'do_cache': True 115 | } 116 | -------------------------------------------------------------------------------- /libs/benchmark/src/console_reporter.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "benchmark/reporter.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "check.h" 23 | #include "colorprint.h" 24 | #include "string_util.h" 25 | #include "walltime.h" 26 | 27 | namespace benchmark { 28 | 29 | bool ConsoleReporter::ReportContext(const Context& context) { 30 | name_field_width_ = context.name_field_width; 31 | 32 | std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu 33 | << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n"; 34 | 35 | std::cerr << LocalDateTimeString() << "\n"; 36 | 37 | if (context.cpu_scaling_enabled) { 38 | std::cerr << "***WARNING*** CPU scaling is enabled, the benchmark " 39 | "real time measurements may be noisy and will incure extra " 40 | "overhead.\n"; 41 | } 42 | 43 | #ifndef NDEBUG 44 | std::cerr << "***WARNING*** Library was built as DEBUG. Timings may be " 45 | "affected.\n"; 46 | #endif 47 | 48 | int output_width = fprintf(stdout, "%-*s %10s %10s %10s\n", 49 | static_cast(name_field_width_), "Benchmark", 50 | "Time(ns)", "CPU(ns)", "Iterations"); 51 | std::cout << std::string(output_width - 1, '-') << "\n"; 52 | 53 | return true; 54 | } 55 | 56 | void ConsoleReporter::ReportRuns(const std::vector& reports) { 57 | if (reports.empty()) { 58 | return; 59 | } 60 | 61 | for (Run const& run : reports) { 62 | CHECK_EQ(reports[0].benchmark_name, run.benchmark_name); 63 | PrintRunData(run); 64 | } 65 | 66 | if (reports.size() < 2) { 67 | // We don't report aggregated data if there was a single run. 68 | return; 69 | } 70 | 71 | Run mean_data; 72 | Run stddev_data; 73 | BenchmarkReporter::ComputeStats(reports, &mean_data, &stddev_data); 74 | 75 | // Output using PrintRun. 76 | PrintRunData(mean_data); 77 | PrintRunData(stddev_data); 78 | } 79 | 80 | void ConsoleReporter::PrintRunData(const Run& result) { 81 | // Format bytes per second 82 | std::string rate; 83 | if (result.bytes_per_second > 0) { 84 | rate = StrCat(" ", HumanReadableNumber(result.bytes_per_second), "B/s"); 85 | } 86 | 87 | // Format items per second 88 | std::string items; 89 | if (result.items_per_second > 0) { 90 | items = StrCat(" ", HumanReadableNumber(result.items_per_second), 91 | " items/s"); 92 | } 93 | 94 | double const multiplier = 1e9; // nano second multiplier 95 | ColorPrintf(COLOR_GREEN, "%-*s ", 96 | name_field_width_, result.benchmark_name.c_str()); 97 | if (result.iterations == 0) { 98 | ColorPrintf(COLOR_YELLOW, "%10.0f %10.0f ", 99 | result.real_accumulated_time * multiplier, 100 | result.cpu_accumulated_time * multiplier); 101 | } else { 102 | ColorPrintf(COLOR_YELLOW, "%10.0f %10.0f ", 103 | (result.real_accumulated_time * multiplier) / 104 | (static_cast(result.iterations)), 105 | (result.cpu_accumulated_time * multiplier) / 106 | (static_cast(result.iterations))); 107 | } 108 | ColorPrintf(COLOR_CYAN, "%10lld", result.iterations); 109 | ColorPrintf(COLOR_DEFAULT, "%*s %*s %s\n", 110 | 13, rate.c_str(), 111 | 18, items.c_str(), 112 | result.report_label.c_str()); 113 | } 114 | 115 | } // end namespace benchmark 116 | -------------------------------------------------------------------------------- /libs/gtest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: wan@google.com (Zhanyong Wan) 31 | 32 | #include "gtest/gtest-typed-test.h" 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | // Verifies that registered_tests match the test names in 49 | // defined_test_names_; returns registered_tests if successful, or 50 | // aborts the program otherwise. 51 | const char* TypedTestCasePState::VerifyRegisteredTestNames( 52 | const char* file, int line, const char* registered_tests) { 53 | typedef ::std::set::const_iterator DefinedTestIter; 54 | registered_ = true; 55 | 56 | // Skip initial whitespace in registered_tests since some 57 | // preprocessors prefix stringizied literals with whitespace. 58 | registered_tests = SkipSpaces(registered_tests); 59 | 60 | Message errors; 61 | ::std::set tests; 62 | for (const char* names = registered_tests; names != NULL; 63 | names = SkipComma(names)) { 64 | const String name = GetPrefixUntilComma(names); 65 | if (tests.count(name) != 0) { 66 | errors << "Test " << name << " is listed more than once.\n"; 67 | continue; 68 | } 69 | 70 | bool found = false; 71 | for (DefinedTestIter it = defined_test_names_.begin(); 72 | it != defined_test_names_.end(); 73 | ++it) { 74 | if (name == *it) { 75 | found = true; 76 | break; 77 | } 78 | } 79 | 80 | if (found) { 81 | tests.insert(name); 82 | } else { 83 | errors << "No test named " << name 84 | << " can be found in this test case.\n"; 85 | } 86 | } 87 | 88 | for (DefinedTestIter it = defined_test_names_.begin(); 89 | it != defined_test_names_.end(); 90 | ++it) { 91 | if (tests.count(*it) == 0) { 92 | errors << "You forgot to list test " << *it << ".\n"; 93 | } 94 | } 95 | 96 | const String& errors_str = errors.GetString(); 97 | if (errors_str != "") { 98 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 99 | errors_str.c_str()); 100 | fflush(stderr); 101 | posix::Abort(); 102 | } 103 | 104 | return registered_tests; 105 | } 106 | 107 | #endif // GTEST_HAS_TYPED_TEST_P 108 | 109 | } // namespace internal 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /src/util/shared_ptr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace ptr 7 | { 8 | // a shared_ptr that's only 8 bytes in size 9 | template 10 | struct small_shared_ptr 11 | { 12 | small_shared_ptr() noexcept 13 | : storage(nullptr) 14 | { 15 | } 16 | template 17 | static small_shared_ptr make(Arguments &&... arguments) 18 | { 19 | small_shared_ptr to_return; 20 | to_return.storage = new Storage(std::forward(arguments)...); 21 | return to_return; 22 | } 23 | small_shared_ptr(const small_shared_ptr & other) noexcept 24 | : storage(other.storage) 25 | { 26 | if (storage) storage->ref_count.increment(); 27 | } 28 | small_shared_ptr(small_shared_ptr && other) noexcept 29 | : storage(other.storage) 30 | { 31 | other.storage = nullptr; 32 | } 33 | small_shared_ptr & operator=(small_shared_ptr other) noexcept 34 | { 35 | swap(other); 36 | return *this; 37 | } 38 | ~small_shared_ptr() noexcept 39 | { 40 | if (storage && storage->ref_count.decrement()) delete storage; 41 | } 42 | explicit operator bool() const noexcept 43 | { 44 | return static_cast(storage); 45 | } 46 | T & operator*() const noexcept 47 | { 48 | return storage->object; 49 | } 50 | T * operator->() const noexcept 51 | { 52 | return get(); 53 | } 54 | T * get() const noexcept 55 | { 56 | return std::addressof(storage->object); 57 | } 58 | void reset() noexcept 59 | { 60 | *this = small_shared_ptr(); 61 | } 62 | void reset(std::nullptr_t) noexcept 63 | { 64 | *this = small_shared_ptr(); 65 | } 66 | bool unique() const noexcept 67 | { 68 | return storage->ref_count.unique(); 69 | } 70 | bool operator==(const small_shared_ptr & other) const noexcept 71 | { 72 | return storage == other.storage; 73 | } 74 | bool operator==(std::nullptr_t) const noexcept 75 | { 76 | return storage == nullptr; 77 | } 78 | bool operator!=(const small_shared_ptr & other) const noexcept 79 | { 80 | return !(*this == other); 81 | } 82 | bool operator!=(std::nullptr_t) const noexcept 83 | { 84 | return !(*this == nullptr); 85 | } 86 | bool operator<(const small_shared_ptr & other) const noexcept 87 | { 88 | return storage < other.storage; 89 | } 90 | bool operator<=(const small_shared_ptr & other) const noexcept 91 | { 92 | return !(other < *this); 93 | } 94 | bool operator>(const small_shared_ptr & other) const noexcept 95 | { 96 | return other < *this; 97 | } 98 | bool operator>=(const small_shared_ptr & other) const noexcept 99 | { 100 | return !(*this < other); 101 | } 102 | void swap(small_shared_ptr & other) noexcept 103 | { 104 | std::swap(storage, other.storage); 105 | } 106 | 107 | private: 108 | struct ReferenceCount 109 | { 110 | ReferenceCount() 111 | : ref_count(1) 112 | { 113 | } 114 | 115 | void increment() 116 | { 117 | ref_count.fetch_add(1, std::memory_order_relaxed); 118 | } 119 | bool decrement() 120 | { 121 | if (ref_count.fetch_sub(1, std::memory_order_release) == 1) 122 | { 123 | std::atomic_thread_fence(std::memory_order_acquire); 124 | return true; 125 | } 126 | else 127 | return false; 128 | } 129 | bool unique() const 130 | { 131 | return ref_count == 1; 132 | } 133 | private: 134 | std::atomic ref_count; 135 | }; 136 | 137 | struct Storage 138 | { 139 | template 140 | Storage(Arguments &&... arguments) 141 | : object(std::forward(arguments)...) 142 | { 143 | } 144 | T object; 145 | ReferenceCount ref_count; 146 | }; 147 | Storage * storage; 148 | }; 149 | template 150 | inline bool operator==(std::nullptr_t, const small_shared_ptr & rhs) 151 | { 152 | return rhs == nullptr; 153 | } 154 | template 155 | inline bool operator!=(std::nullptr_t, const small_shared_ptr & rhs) 156 | { 157 | return rhs != nullptr; 158 | } 159 | 160 | template 161 | inline void swap(small_shared_ptr & lhs, small_shared_ptr & rhs) 162 | { 163 | lhs.swap(rhs); 164 | } 165 | 166 | template 167 | inline small_shared_ptr make_shared(Arguments &&... arguments) 168 | { 169 | return small_shared_ptr::make(std::forward(arguments)...); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /libs/benchmark/src/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef BENCHMARK_MUTEX_H_ 2 | #define BENCHMARK_MUTEX_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Enable thread safety attributes only with clang. 8 | // The attributes can be safely erased when compiling with other compilers. 9 | #if defined(HAVE_THREAD_SAFETY_ATTRIBUTES) 10 | #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 11 | #else 12 | #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 13 | #endif 14 | 15 | #define CAPABILITY(x) \ 16 | THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 17 | 18 | #define SCOPED_CAPABILITY \ 19 | THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 20 | 21 | #define GUARDED_BY(x) \ 22 | THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 23 | 24 | #define PT_GUARDED_BY(x) \ 25 | THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 26 | 27 | #define ACQUIRED_BEFORE(...) \ 28 | THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 29 | 30 | #define ACQUIRED_AFTER(...) \ 31 | THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 32 | 33 | #define REQUIRES(...) \ 34 | THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 35 | 36 | #define REQUIRES_SHARED(...) \ 37 | THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 38 | 39 | #define ACQUIRE(...) \ 40 | THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 41 | 42 | #define ACQUIRE_SHARED(...) \ 43 | THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 44 | 45 | #define RELEASE(...) \ 46 | THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 47 | 48 | #define RELEASE_SHARED(...) \ 49 | THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 50 | 51 | #define TRY_ACQUIRE(...) \ 52 | THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 53 | 54 | #define TRY_ACQUIRE_SHARED(...) \ 55 | THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 56 | 57 | #define EXCLUDES(...) \ 58 | THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 59 | 60 | #define ASSERT_CAPABILITY(x) \ 61 | THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 62 | 63 | #define ASSERT_SHARED_CAPABILITY(x) \ 64 | THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 65 | 66 | #define RETURN_CAPABILITY(x) \ 67 | THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 68 | 69 | #define NO_THREAD_SAFETY_ANALYSIS \ 70 | THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 71 | 72 | 73 | namespace benchmark { 74 | 75 | typedef std::condition_variable Condition; 76 | 77 | // NOTE: Wrappers for std::mutex and std::unique_lock are provided so that 78 | // we can annotate them with thread safety attributes and use the 79 | // -Wthread-safety warning with clang. The standard library types cannot be 80 | // used directly because they do not provided the required annotations. 81 | class CAPABILITY("mutex") Mutex 82 | { 83 | public: 84 | Mutex() {} 85 | 86 | void lock() ACQUIRE() { mut_.lock(); } 87 | void unlock() RELEASE() { mut_.unlock(); } 88 | std::mutex& native_handle() { 89 | return mut_; 90 | } 91 | private: 92 | std::mutex mut_; 93 | }; 94 | 95 | 96 | class SCOPED_CAPABILITY MutexLock 97 | { 98 | typedef std::unique_lock MutexLockImp; 99 | public: 100 | MutexLock(Mutex& m) ACQUIRE(m) : ml_(m.native_handle()) 101 | { } 102 | ~MutexLock() RELEASE() {} 103 | MutexLockImp& native_handle() { return ml_; } 104 | private: 105 | MutexLockImp ml_; 106 | }; 107 | 108 | 109 | class Notification 110 | { 111 | public: 112 | Notification() : notified_yet_(false) { } 113 | 114 | void WaitForNotification() const EXCLUDES(mutex_) { 115 | MutexLock m_lock(mutex_); 116 | auto notified_fn = [this]() REQUIRES(mutex_) { 117 | return this->HasBeenNotified(); 118 | }; 119 | cv_.wait(m_lock.native_handle(), notified_fn); 120 | } 121 | 122 | void Notify() EXCLUDES(mutex_) { 123 | { 124 | MutexLock lock(mutex_); 125 | notified_yet_ = 1; 126 | } 127 | cv_.notify_all(); 128 | } 129 | 130 | private: 131 | bool HasBeenNotified() const REQUIRES(mutex_) { 132 | return notified_yet_; 133 | } 134 | 135 | mutable Mutex mutex_; 136 | mutable std::condition_variable cv_; 137 | bool notified_yet_ GUARDED_BY(mutex_); 138 | }; 139 | 140 | } // end namespace benchmark 141 | 142 | #endif // BENCHMARK_MUTEX_H_ 143 | -------------------------------------------------------------------------------- /libs/benchmark/include/benchmark/reporter.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #ifndef BENCHMARK_REPORTER_H_ 15 | #define BENCHMARK_REPORTER_H_ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "benchmark_api.h" // For forward declaration of BenchmarkReporter 22 | 23 | namespace benchmark { 24 | 25 | // Interface for custom benchmark result printers. 26 | // By default, benchmark reports are printed to stdout. However an application 27 | // can control the destination of the reports by calling 28 | // RunSpecifiedBenchmarks and passing it a custom reporter object. 29 | // The reporter object must implement the following interface. 30 | class BenchmarkReporter { 31 | public: 32 | struct Context { 33 | int num_cpus; 34 | double mhz_per_cpu; 35 | bool cpu_scaling_enabled; 36 | 37 | // The number of chars in the longest benchmark name. 38 | size_t name_field_width; 39 | }; 40 | 41 | struct Run { 42 | Run() : 43 | iterations(1), 44 | real_accumulated_time(0), 45 | cpu_accumulated_time(0), 46 | bytes_per_second(0), 47 | items_per_second(0), 48 | max_heapbytes_used(0) {} 49 | 50 | std::string benchmark_name; 51 | std::string report_label; // Empty if not set by benchmark. 52 | int64_t iterations; 53 | double real_accumulated_time; 54 | double cpu_accumulated_time; 55 | 56 | // Zero if not set by benchmark. 57 | double bytes_per_second; 58 | double items_per_second; 59 | 60 | // This is set to 0.0 if memory tracing is not enabled. 61 | double max_heapbytes_used; 62 | }; 63 | 64 | // Called once for every suite of benchmarks run. 65 | // The parameter "context" contains information that the 66 | // reporter may wish to use when generating its report, for example the 67 | // platform under which the benchmarks are running. The benchmark run is 68 | // never started if this function returns false, allowing the reporter 69 | // to skip runs based on the context information. 70 | virtual bool ReportContext(const Context& context) = 0; 71 | 72 | // Called once for each group of benchmark runs, gives information about 73 | // cpu-time and heap memory usage during the benchmark run. 74 | // Note that all the grouped benchmark runs should refer to the same 75 | // benchmark, thus have the same name. 76 | virtual void ReportRuns(const std::vector& report) = 0; 77 | 78 | // Called once and only once after ever group of benchmarks is run and 79 | // reported. 80 | virtual void Finalize(); 81 | 82 | virtual ~BenchmarkReporter(); 83 | protected: 84 | static void ComputeStats(std::vector const& reports, Run* mean, Run* stddev); 85 | }; 86 | 87 | // Simple reporter that outputs benchmark data to the console. This is the 88 | // default reporter used by RunSpecifiedBenchmarks(). 89 | class ConsoleReporter : public BenchmarkReporter { 90 | public: 91 | virtual bool ReportContext(const Context& context); 92 | virtual void ReportRuns(const std::vector& reports); 93 | protected: 94 | virtual void PrintRunData(const Run& report); 95 | 96 | size_t name_field_width_; 97 | }; 98 | 99 | class JSONReporter : public BenchmarkReporter { 100 | public: 101 | JSONReporter() : first_report_(true) {} 102 | virtual bool ReportContext(const Context& context); 103 | virtual void ReportRuns(const std::vector& reports); 104 | virtual void Finalize(); 105 | 106 | private: 107 | void PrintRunData(const Run& report); 108 | 109 | bool first_report_; 110 | }; 111 | 112 | class CSVReporter : public BenchmarkReporter { 113 | public: 114 | virtual bool ReportContext(const Context& context); 115 | virtual void ReportRuns(const std::vector& reports); 116 | 117 | private: 118 | void PrintRunData(const Run& report); 119 | }; 120 | 121 | } // end namespace benchmark 122 | #endif // BENCHMARK_REPORTER_H_ 123 | -------------------------------------------------------------------------------- /libs/gtest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Author: mheule@google.com (Markus Heule) 31 | // 32 | // The Google C++ Testing Framework (Google Test) 33 | 34 | #include "gtest/gtest-test-part.h" 35 | 36 | // Indicates that this translation unit is part of Google Test's 37 | // implementation. It must come before gtest-internal-inl.h is 38 | // included, or there will be a compiler error. This trick is to 39 | // prevent a user from accidentally including gtest-internal-inl.h in 40 | // his code. 41 | #define GTEST_IMPLEMENTATION_ 1 42 | #include "src/gtest-internal-inl.h" 43 | #undef GTEST_IMPLEMENTATION_ 44 | 45 | namespace testing { 46 | 47 | using internal::GetUnitTestImpl; 48 | 49 | // Gets the summary of the failure message by omitting the stack trace 50 | // in it. 51 | internal::String TestPartResult::ExtractSummary(const char* message) { 52 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 53 | return stack_trace == NULL ? internal::String(message) : 54 | internal::String(message, stack_trace - message); 55 | } 56 | 57 | // Prints a TestPartResult object. 58 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 59 | return os 60 | << result.file_name() << ":" << result.line_number() << ": " 61 | << (result.type() == TestPartResult::kSuccess ? "Success" : 62 | result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : 63 | "Non-fatal failure") << ":\n" 64 | << result.message() << std::endl; 65 | } 66 | 67 | // Appends a TestPartResult to the array. 68 | void TestPartResultArray::Append(const TestPartResult& result) { 69 | array_.push_back(result); 70 | } 71 | 72 | // Returns the TestPartResult at the given index (0-based). 73 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 74 | if (index < 0 || index >= size()) { 75 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 76 | internal::posix::Abort(); 77 | } 78 | 79 | return array_[index]; 80 | } 81 | 82 | // Returns the number of TestPartResult objects in the array. 83 | int TestPartResultArray::size() const { 84 | return static_cast(array_.size()); 85 | } 86 | 87 | namespace internal { 88 | 89 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 90 | : has_new_fatal_failure_(false), 91 | original_reporter_(GetUnitTestImpl()-> 92 | GetTestPartResultReporterForCurrentThread()) { 93 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 94 | } 95 | 96 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 97 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 98 | original_reporter_); 99 | } 100 | 101 | void HasNewFatalFailureHelper::ReportTestPartResult( 102 | const TestPartResult& result) { 103 | if (result.fatally_failed()) 104 | has_new_fatal_failure_ = true; 105 | original_reporter_->ReportTestPartResult(result); 106 | } 107 | 108 | } // namespace internal 109 | 110 | } // namespace testing 111 | -------------------------------------------------------------------------------- /src/util/type_erasure.cpp: -------------------------------------------------------------------------------- 1 | #include "type_erasure.hpp" 2 | 3 | #ifndef DISABLE_TESTS 4 | #include 5 | #include 6 | namespace 7 | { 8 | TEST(type_erasure, moveable) 9 | { 10 | BaseTypeErasure<8, MoveVTable> movable(std::unique_ptr(new int(5))); 11 | ASSERT_EQ(typeid(std::unique_ptr), movable.target_type()); 12 | ASSERT_EQ(5, **movable.target>()); 13 | } 14 | 15 | TEST(type_erasure, copyable) 16 | { 17 | BaseTypeErasure<8, CopyVTable> a(5); 18 | ASSERT_EQ(typeid(int), a.target_type()); 19 | ASSERT_EQ(5, *a.target()); 20 | a = 3.3f; 21 | ASSERT_EQ(typeid(float), a.target_type()); 22 | ASSERT_EQ(3.3f, *a.target()); 23 | a = a; 24 | ASSERT_EQ(typeid(float), a.target_type()); 25 | ASSERT_EQ(3.3f, *a.target()); 26 | const BaseTypeErasure<8, CopyVTable> b = a; 27 | ASSERT_EQ(typeid(float), b.target_type()); 28 | ASSERT_EQ(3.3f, *b.target()); 29 | } 30 | 31 | struct CtorDtorCounter 32 | { 33 | CtorDtorCounter(int & ctor_count, int & dtor_count) 34 | : ctor_count(ctor_count), dtor_count(dtor_count) 35 | { 36 | ++ctor_count; 37 | } 38 | CtorDtorCounter(const CtorDtorCounter & other) 39 | : ctor_count(other.ctor_count), dtor_count(other.dtor_count) 40 | { 41 | ++ctor_count; 42 | } 43 | ~CtorDtorCounter() 44 | { 45 | ++dtor_count; 46 | } 47 | 48 | int & ctor_count; 49 | int & dtor_count; 50 | }; 51 | 52 | TEST(type_erasure, copy_assign) 53 | { 54 | int ctor_count = 0; 55 | int dtor_count = 0; 56 | { 57 | BaseTypeErasure<8, CopyVTable> a(CtorDtorCounter(ctor_count, dtor_count)); 58 | BaseTypeErasure<8, CopyVTable> b(CtorDtorCounter(ctor_count, dtor_count)); 59 | a = b; 60 | } 61 | ASSERT_EQ(ctor_count, dtor_count); 62 | } 63 | 64 | struct LargerEnoughToStompTheStack 65 | { 66 | LargerEnoughToStompTheStack(int value) 67 | { 68 | for (auto it = std::begin(a); it != std::end(a); ++it) 69 | { 70 | *it = value + int(it - std::begin(a)); 71 | } 72 | } 73 | 74 | int a[8192]; 75 | 76 | bool operator==(const LargerEnoughToStompTheStack & other) const 77 | { 78 | return std::equal(std::begin(a), std::end(a), std::begin(other.a)); 79 | } 80 | }; 81 | 82 | TEST(type_erasure, heap_allocated) 83 | { 84 | static_assert(sizeof(LargerEnoughToStompTheStack) > sizeof(BaseTypeErasure<8, CopyVTable>), "has to be heap allocated for this test"); 85 | BaseTypeErasure<8, CopyVTable> a = LargerEnoughToStompTheStack(5); 86 | ASSERT_EQ(typeid(LargerEnoughToStompTheStack), a.target_type()); 87 | ASSERT_EQ(LargerEnoughToStompTheStack(5), *a.target()); 88 | a = LargerEnoughToStompTheStack(6); 89 | ASSERT_EQ(typeid(LargerEnoughToStompTheStack), a.target_type()); 90 | ASSERT_EQ(LargerEnoughToStompTheStack(6), *a.target()); 91 | a = 5; 92 | ASSERT_EQ(typeid(int), a.target_type()); 93 | ASSERT_EQ(5, *a.target()); 94 | } 95 | 96 | template 97 | struct RegularCopyVtable : RegularVTable, CopyVTable 98 | { 99 | template 100 | RegularCopyVtable(T *) 101 | : RegularVTable(static_cast(nullptr)) 102 | , CopyVTable(static_cast(nullptr)) 103 | { 104 | } 105 | }; 106 | 107 | TEST(type_erasure, comparisons) 108 | { 109 | typedef RegularTypeErasure Regular; 110 | ASSERT_LT(Regular(5), Regular(6)); 111 | ASSERT_GT(Regular(5), Regular(4)); 112 | ASSERT_EQ(Regular(5), Regular(5)); 113 | ASSERT_NE(Regular(6), Regular(5)); 114 | } 115 | 116 | template 117 | using MovableFunction = CallableTypeErasure; 118 | static_assert(sizeof(MovableFunction) == sizeof(void *) * 4, "this should only have a vtable pointer, a call pointer and my 16 bytes of storage"); 119 | 120 | TEST(type_erasure, callable_no_argument) 121 | { 122 | int a = 1; 123 | MovableFunction no_arg = [&a]{ a = 5; }; 124 | no_arg(); 125 | ASSERT_EQ(5, a); 126 | } 127 | TEST(type_erasure, callable_with_argument) 128 | { 129 | int a = 1; 130 | 131 | MovableFunction with_arg = [&a](int value) 132 | { 133 | return a++ == value; 134 | }; 135 | ASSERT_TRUE(with_arg(1)); 136 | ASSERT_EQ(2, a); 137 | } 138 | TEST(type_erasure, callable_mutable) 139 | { 140 | MovableFunction with_state = [a = 5]() mutable 141 | { 142 | return a++; 143 | }; 144 | ASSERT_EQ(5, with_state()); 145 | ASSERT_EQ(6, with_state()); 146 | } 147 | } 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /libs/benchmark/test/benchmark_test.cc: -------------------------------------------------------------------------------- 1 | #include "benchmark/benchmark.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #if defined(__GNUC__) 19 | # define BENCHMARK_NOINLINE __attribute__((noinline)) 20 | #else 21 | # define BENCHMARK_NOINLINE 22 | #endif 23 | 24 | namespace { 25 | 26 | int BENCHMARK_NOINLINE Factorial(uint32_t n) { 27 | return (n == 1) ? 1 : n * Factorial(n - 1); 28 | } 29 | 30 | double CalculatePi(int depth) { 31 | double pi = 0.0; 32 | for (int i = 0; i < depth; ++i) { 33 | double numerator = static_cast(((i % 2) * 2) - 1); 34 | double denominator = static_cast((2 * i) - 1); 35 | pi += numerator / denominator; 36 | } 37 | return (pi - 1.0) * 4; 38 | } 39 | 40 | std::set ConstructRandomSet(int size) { 41 | std::set s; 42 | for (int i = 0; i < size; ++i) 43 | s.insert(i); 44 | return s; 45 | } 46 | 47 | std::mutex test_vector_mu; 48 | std::vector* test_vector = nullptr; 49 | 50 | } // end namespace 51 | 52 | static void BM_Factorial(benchmark::State& state) { 53 | int fac_42 = 0; 54 | while (state.KeepRunning()) 55 | fac_42 = Factorial(8); 56 | // Prevent compiler optimizations 57 | std::stringstream ss; 58 | ss << fac_42; 59 | state.SetLabel(ss.str()); 60 | } 61 | BENCHMARK(BM_Factorial); 62 | BENCHMARK(BM_Factorial)->UseRealTime(); 63 | 64 | static void BM_CalculatePiRange(benchmark::State& state) { 65 | double pi = 0.0; 66 | while (state.KeepRunning()) 67 | pi = CalculatePi(state.range_x()); 68 | std::stringstream ss; 69 | ss << pi; 70 | state.SetLabel(ss.str()); 71 | } 72 | BENCHMARK_RANGE(BM_CalculatePiRange, 1, 1024 * 1024); 73 | 74 | static void BM_CalculatePi(benchmark::State& state) { 75 | static const int depth = 1024; 76 | while (state.KeepRunning()) { 77 | benchmark::DoNotOptimize(CalculatePi(depth)); 78 | } 79 | } 80 | BENCHMARK(BM_CalculatePi)->Threads(8); 81 | BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32); 82 | BENCHMARK(BM_CalculatePi)->ThreadPerCpu(); 83 | 84 | static void BM_SetInsert(benchmark::State& state) { 85 | while (state.KeepRunning()) { 86 | state.PauseTiming(); 87 | std::set data = ConstructRandomSet(state.range_x()); 88 | state.ResumeTiming(); 89 | for (int j = 0; j < state.range_y(); ++j) 90 | data.insert(rand()); 91 | } 92 | state.SetItemsProcessed(state.iterations() * state.range_y()); 93 | state.SetBytesProcessed(state.iterations() * state.range_y() * sizeof(int)); 94 | } 95 | BENCHMARK(BM_SetInsert)->RangePair(1<<10,8<<10, 1,10); 96 | 97 | template 98 | static void BM_Sequential(benchmark::State& state) { 99 | ValueType v = 42; 100 | while (state.KeepRunning()) { 101 | Container c; 102 | for (int i = state.range_x(); --i; ) 103 | c.push_back(v); 104 | } 105 | const size_t items_processed = state.iterations() * state.range_x(); 106 | state.SetItemsProcessed(items_processed); 107 | state.SetBytesProcessed(items_processed * sizeof(v)); 108 | } 109 | BENCHMARK_TEMPLATE2(BM_Sequential, std::vector, int)->Range(1 << 0, 1 << 10); 110 | BENCHMARK_TEMPLATE(BM_Sequential, std::list)->Range(1 << 0, 1 << 10); 111 | // Test the variadic version of BENCHMARK_TEMPLATE in C++11 and beyond. 112 | #if __cplusplus >= 201103L 113 | BENCHMARK_TEMPLATE(BM_Sequential, std::vector, int)->Arg(512); 114 | #endif 115 | 116 | static void BM_StringCompare(benchmark::State& state) { 117 | std::string s1(state.range_x(), '-'); 118 | std::string s2(state.range_x(), '-'); 119 | while (state.KeepRunning()) 120 | benchmark::DoNotOptimize(s1.compare(s2)); 121 | } 122 | BENCHMARK(BM_StringCompare)->Range(1, 1<<20); 123 | 124 | static void BM_SetupTeardown(benchmark::State& state) { 125 | if (state.thread_index == 0) { 126 | // No need to lock test_vector_mu here as this is running single-threaded. 127 | test_vector = new std::vector(); 128 | } 129 | int i = 0; 130 | while (state.KeepRunning()) { 131 | std::lock_guard l(test_vector_mu); 132 | if (i%2 == 0) 133 | test_vector->push_back(i); 134 | else 135 | test_vector->pop_back(); 136 | ++i; 137 | } 138 | if (state.thread_index == 0) { 139 | delete test_vector; 140 | } 141 | } 142 | BENCHMARK(BM_SetupTeardown)->ThreadPerCpu(); 143 | 144 | static void BM_LongTest(benchmark::State& state) { 145 | double tracker = 0.0; 146 | while (state.KeepRunning()) { 147 | for (int i = 0; i < state.range_x(); ++i) 148 | benchmark::DoNotOptimize(tracker += i); 149 | } 150 | } 151 | BENCHMARK(BM_LongTest)->Range(1<<16,1<<28); 152 | 153 | BENCHMARK_MAIN() 154 | 155 | -------------------------------------------------------------------------------- /libs/benchmark/src/json_reporter.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "benchmark/reporter.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "string_util.h" 23 | #include "walltime.h" 24 | 25 | namespace benchmark { 26 | 27 | namespace { 28 | 29 | std::string FormatKV(std::string const& key, std::string const& value) { 30 | return StringPrintF("\"%s\": \"%s\"", key.c_str(), value.c_str()); 31 | } 32 | 33 | std::string FormatKV(std::string const& key, const char* value) { 34 | return StringPrintF("\"%s\": \"%s\"", key.c_str(), value); 35 | } 36 | 37 | std::string FormatKV(std::string const& key, bool value) { 38 | return StringPrintF("\"%s\": %s", key.c_str(), value ? "true" : "false"); 39 | } 40 | 41 | std::string FormatKV(std::string const& key, int64_t value) { 42 | std::stringstream ss; 43 | ss << '"' << key << "\": " << value; 44 | return ss.str(); 45 | } 46 | 47 | int64_t RoundDouble(double v) { 48 | return static_cast(v + 0.5); 49 | } 50 | 51 | } // end namespace 52 | 53 | bool JSONReporter::ReportContext(const Context& context) { 54 | std::ostream& out = std::cout; 55 | 56 | out << "{\n"; 57 | std::string inner_indent(2, ' '); 58 | 59 | // Open context block and print context information. 60 | out << inner_indent << "\"context\": {\n"; 61 | std::string indent(4, ' '); 62 | 63 | std::string walltime_value = LocalDateTimeString(); 64 | out << indent << FormatKV("date", walltime_value) << ",\n"; 65 | 66 | out << indent 67 | << FormatKV("num_cpus", static_cast(context.num_cpus)) 68 | << ",\n"; 69 | out << indent 70 | << FormatKV("mhz_per_cpu", RoundDouble(context.mhz_per_cpu)) 71 | << ",\n"; 72 | out << indent 73 | << FormatKV("cpu_scaling_enabled", context.cpu_scaling_enabled) 74 | << ",\n"; 75 | 76 | #if defined(NDEBUG) 77 | const char build_type[] = "release"; 78 | #else 79 | const char build_type[] = "debug"; 80 | #endif 81 | out << indent << FormatKV("library_build_type", build_type) << "\n"; 82 | // Close context block and open the list of benchmarks. 83 | out << inner_indent << "},\n"; 84 | out << inner_indent << "\"benchmarks\": [\n"; 85 | return true; 86 | } 87 | 88 | void JSONReporter::ReportRuns(std::vector const& reports) { 89 | if (reports.empty()) { 90 | return; 91 | } 92 | std::string indent(4, ' '); 93 | std::ostream& out = std::cout; 94 | if (!first_report_) { 95 | out << ",\n"; 96 | } 97 | first_report_ = false; 98 | std::vector reports_cp = reports; 99 | if (reports.size() >= 2) { 100 | Run mean_data; 101 | Run stddev_data; 102 | BenchmarkReporter::ComputeStats(reports, &mean_data, &stddev_data); 103 | reports_cp.push_back(mean_data); 104 | reports_cp.push_back(stddev_data); 105 | } 106 | for (auto it = reports_cp.begin(); it != reports_cp.end(); ++it) { 107 | out << indent << "{\n"; 108 | PrintRunData(*it); 109 | out << indent << '}'; 110 | auto it_cp = it; 111 | if (++it_cp != reports_cp.end()) { 112 | out << ",\n"; 113 | } 114 | } 115 | } 116 | 117 | void JSONReporter::Finalize() { 118 | // Close the list of benchmarks and the top level object. 119 | std::cout << "\n ]\n}\n"; 120 | } 121 | 122 | void JSONReporter::PrintRunData(Run const& run) { 123 | double const multiplier = 1e9; // nano second multiplier 124 | double cpu_time = run.cpu_accumulated_time * multiplier; 125 | double real_time = run.real_accumulated_time * multiplier; 126 | if (run.iterations != 0) { 127 | real_time = real_time / static_cast(run.iterations); 128 | cpu_time = cpu_time / static_cast(run.iterations); 129 | } 130 | 131 | std::string indent(6, ' '); 132 | std::ostream& out = std::cout; 133 | out << indent 134 | << FormatKV("name", run.benchmark_name) 135 | << ",\n"; 136 | out << indent 137 | << FormatKV("iterations", run.iterations) 138 | << ",\n"; 139 | out << indent 140 | << FormatKV("real_time", RoundDouble(real_time)) 141 | << ",\n"; 142 | out << indent 143 | << FormatKV("cpu_time", RoundDouble(cpu_time)); 144 | if (run.bytes_per_second > 0.0) { 145 | out << ",\n" << indent 146 | << FormatKV("bytes_per_second", RoundDouble(run.bytes_per_second)); 147 | } 148 | if (run.items_per_second > 0.0) { 149 | out << ",\n" << indent 150 | << FormatKV("items_per_second", RoundDouble(run.items_per_second)); 151 | } 152 | if (!run.report_label.empty()) { 153 | out << ",\n" << indent 154 | << FormatKV("label", run.report_label); 155 | } 156 | out << '\n'; 157 | } 158 | 159 | } // end namespace benchmark 160 | -------------------------------------------------------------------------------- /src/util/string/hashed_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | template> 8 | struct HashedString 9 | { 10 | HashedString(const char * str) 11 | : str(ptr::make_shared(str)), hash(HashFunction()(*this->str)) 12 | { 13 | } 14 | 15 | HashedString(std::string str) 16 | : str(ptr::make_shared(std::move(str))), hash(HashFunction()(*this->str)) 17 | { 18 | } 19 | 20 | bool operator==(const HashedString & other) const noexcept 21 | { 22 | return hash == other.hash && (str == other.str || *str == *other.str); 23 | } 24 | bool operator==(const std::string & other) const noexcept 25 | { 26 | return *str == other; 27 | } 28 | bool operator==(const char * other) const noexcept 29 | { 30 | return *str == other; 31 | } 32 | bool operator!=(const HashedString & other) const noexcept 33 | { 34 | return !(*this == other); 35 | } 36 | bool operator!=(const std::string & other) const noexcept 37 | { 38 | return !(*this == other); 39 | } 40 | bool operator!=(const char * other) const noexcept 41 | { 42 | return !(*this == other); 43 | } 44 | bool operator<(const HashedString & other) const noexcept 45 | { 46 | return *str < *other.str; 47 | } 48 | bool operator<(const std::string & other) const noexcept 49 | { 50 | return *str < other; 51 | } 52 | bool operator<(const char * other) const noexcept 53 | { 54 | return *str < other; 55 | } 56 | bool operator>(const HashedString & other) const noexcept 57 | { 58 | return other < *this; 59 | } 60 | bool operator>(const std::string & other) const noexcept 61 | { 62 | return *str > other; 63 | } 64 | bool operator>(const char * other) const noexcept 65 | { 66 | return *str > other; 67 | } 68 | bool operator<=(const HashedString & other) const noexcept 69 | { 70 | return !(*this > other); 71 | } 72 | bool operator<=(const std::string & other) const noexcept 73 | { 74 | return *str <= other; 75 | } 76 | bool operator<=(const char * other) const noexcept 77 | { 78 | return *str <= other; 79 | } 80 | bool operator>=(const HashedString & other) const noexcept 81 | { 82 | return !(*this < other); 83 | } 84 | bool operator>=(const std::string & other) const noexcept 85 | { 86 | return *str >= other; 87 | } 88 | bool operator>=(const char * other) const noexcept 89 | { 90 | return *str >= other; 91 | } 92 | 93 | const std::string & get() const noexcept 94 | { 95 | return *str; 96 | } 97 | const char * c_str() const noexcept 98 | { 99 | return str->c_str(); 100 | } 101 | HashType get_hash() const noexcept 102 | { 103 | return hash; 104 | } 105 | 106 | private: 107 | ptr::small_shared_ptr str; 108 | HashType hash; 109 | }; 110 | 111 | namespace std 112 | { 113 | template 114 | struct hash> 115 | { 116 | size_t operator()(const HashedString & object) const noexcept 117 | { 118 | return object.get_hash(); 119 | } 120 | }; 121 | } 122 | 123 | template 124 | inline bool operator==(const std::string & lhs, const HashedString & rhs) noexcept 125 | { 126 | return rhs == lhs; 127 | } 128 | template 129 | inline bool operator==(const char * lhs, const HashedString & rhs) noexcept 130 | { 131 | return rhs == lhs; 132 | } 133 | template 134 | inline bool operator!=(const std::string & lhs, const HashedString & rhs) noexcept 135 | { 136 | return !(lhs == rhs); 137 | } 138 | template 139 | inline bool operator!=(const char * lhs, const HashedString & rhs) noexcept 140 | { 141 | return !(lhs == rhs); 142 | } 143 | template 144 | inline bool operator<(const std::string & lhs, const HashedString & rhs) noexcept 145 | { 146 | return lhs < rhs.get(); 147 | } 148 | template 149 | inline bool operator<(const char * lhs, const HashedString & rhs) noexcept 150 | { 151 | return lhs < rhs.get(); 152 | } 153 | template 154 | inline bool operator>(const std::string & lhs, const HashedString & rhs) noexcept 155 | { 156 | return lhs > rhs.get(); 157 | } 158 | template 159 | inline bool operator>(const char * lhs, const HashedString & rhs) noexcept 160 | { 161 | return lhs > rhs.get(); 162 | } 163 | template 164 | inline bool operator<=(const std::string & lhs, const HashedString & rhs) noexcept 165 | { 166 | return lhs <= rhs.get(); 167 | } 168 | template 169 | inline bool operator<=(const char * lhs, const HashedString & rhs) noexcept 170 | { 171 | return lhs <= rhs.get(); 172 | } 173 | template 174 | inline bool operator>=(const std::string & lhs, const HashedString & rhs) noexcept 175 | { 176 | return lhs >= rhs.get(); 177 | } 178 | template 179 | inline bool operator>=(const char * lhs, const HashedString & rhs) noexcept 180 | { 181 | return lhs >= rhs.get(); 182 | } 183 | -------------------------------------------------------------------------------- /src/debug/asserting_mutex.cpp: -------------------------------------------------------------------------------- 1 | #include "asserting_mutex.hpp" 2 | 3 | 4 | #if !defined(DISABLE_TESTS) && !defined(VALGRIND_BUILD) && !defined(FINAL) 5 | #include 6 | #include 7 | #include 8 | #include "assert_settings.hpp" 9 | #include 10 | 11 | template 12 | bool DoesAssert(T && functor) 13 | { 14 | bool did_assert = false; 15 | assert::ScopedSetAssertCallback change_callback([&](const ::assert::AssertContext &) 16 | { 17 | did_assert = true; 18 | return ::assert::ShouldNotBreak; 19 | }); 20 | functor(); 21 | return did_assert; 22 | } 23 | 24 | TEST(asserting_mutex, single_user) 25 | { 26 | AssertingMutex mutex; 27 | ASSERT_FALSE(DoesAssert([&] 28 | { 29 | std::lock_guard lock(mutex); 30 | })); 31 | } 32 | TEST(asserting_mutex, two_users) 33 | { 34 | AssertingMutex mutex; 35 | ASSERT_TRUE(DoesAssert([&] 36 | { 37 | std::lock_guard lock(mutex); 38 | std::lock_guard second_lock(mutex); 39 | })); 40 | } 41 | 42 | TEST(asserting_mutex, threaded) 43 | { 44 | ASSERT_TRUE(DoesAssert([&] 45 | { 46 | AssertingMutex asserting_mutex; 47 | std::promise first_thread_promise; 48 | std::promise second_thread_promise; 49 | std::thread first([&] 50 | { 51 | std::lock_guard lock(asserting_mutex); 52 | first_thread_promise.set_value(); 53 | second_thread_promise.get_future().get(); 54 | }); 55 | std::thread second([&] 56 | { 57 | std::lock_guard lock(asserting_mutex); 58 | second_thread_promise.set_value(); 59 | first_thread_promise.get_future().get(); 60 | }); 61 | first.join(); 62 | second.join(); 63 | })); 64 | } 65 | 66 | /*TEST(asserting_mutex, DISABLED_test_many_times) 67 | { 68 | int num_tests = 1000; 69 | static constexpr int num_threads = 6; 70 | std::atomic count[num_threads]; 71 | for (int i = 0; i < num_threads; ++i) count[i] = 0; 72 | std::vector threads; 73 | int num_asserts = 0; 74 | for (int i = 0; i < num_tests; ++i) 75 | { 76 | if (DoesAssert([&] 77 | { 78 | threads.clear(); 79 | AssertingMutex mutex; 80 | for (int i = 0; i < num_threads; ++i) 81 | { 82 | threads.emplace_back([i, &mutex, &count] 83 | { 84 | std::lock_guard lock(mutex); 85 | ++count[i]; 86 | }); 87 | } 88 | for (std::thread & thread : threads) 89 | { 90 | thread.join(); 91 | } 92 | })) 93 | { 94 | ++num_asserts; 95 | } 96 | } 97 | //std::cout << num_asserts << std::endl; 98 | for (std::atomic & c : count) 99 | { 100 | ASSERT_EQ(num_tests, c); 101 | } 102 | }*/ 103 | 104 | TEST(asserting_reader_writer_mutex, single_writer) 105 | { 106 | AssertingReaderWriterMutex mutex; 107 | ASSERT_FALSE(DoesAssert([&] 108 | { 109 | std::lock_guard lock(mutex); 110 | })); 111 | } 112 | TEST(asserting_reader_writer_mutex, only_readers) 113 | { 114 | AssertingReaderWriterMutex mutex; 115 | ASSERT_FALSE(DoesAssert([&] 116 | { 117 | std::lock_guard lock(mutex); 118 | })); 119 | ASSERT_FALSE(DoesAssert([&] 120 | { 121 | std::lock_guard lock(mutex); 122 | std::lock_guard second_lock(mutex); 123 | })); 124 | ASSERT_FALSE(DoesAssert([&] 125 | { 126 | std::lock_guard lock(mutex); 127 | std::lock_guard second_lock(mutex); 128 | std::lock_guard third_lock(mutex); 129 | })); 130 | } 131 | TEST(asserting_reader_writer_mutex, multiple_writers) 132 | { 133 | AssertingReaderWriterMutex mutex; 134 | ASSERT_TRUE(DoesAssert([&] 135 | { 136 | std::lock_guard lock(mutex); 137 | std::lock_guard second_lock(mutex); 138 | })); 139 | } 140 | TEST(asserting_reader_writer_mutex, writer_first) 141 | { 142 | AssertingReaderWriterMutex mutex; 143 | ASSERT_TRUE(DoesAssert([&] 144 | { 145 | std::lock_guard lock(mutex); 146 | std::lock_guard second_lock(mutex); 147 | })); 148 | } 149 | TEST(asserting_reader_writer_mutex, reader_first) 150 | { 151 | AssertingReaderWriterMutex mutex; 152 | ASSERT_TRUE(DoesAssert([&] 153 | { 154 | std::lock_guard lock(mutex); 155 | std::lock_guard second_lock(mutex); 156 | })); 157 | } 158 | TEST(asserting_reader_writer_mutex, readers_dont_unlock_too_early) 159 | { 160 | AssertingReaderWriterMutex mutex; 161 | ASSERT_TRUE(DoesAssert([&] 162 | { 163 | std::lock_guard lock(mutex); 164 | { 165 | std::lock_guard second_lock(mutex); 166 | } 167 | std::lock_guard second_lock(mutex); 168 | })); 169 | } 170 | 171 | #ifdef RUN_SLOW_TESTS 172 | 173 | TEST(asserting_reader_writer_mutex, readers_from_different_threads) 174 | { 175 | AssertingReaderWriterMutex mutex; 176 | int num_checks = 100000; 177 | int num_threads = 2; 178 | std::vector threads; 179 | threads.reserve(num_threads); 180 | for (int i = 0; i < num_threads; ++i) 181 | { 182 | threads.emplace_back([&] 183 | { 184 | for (int i = 0; i < num_checks; ++i) 185 | { 186 | std::lock_guard lock(mutex); 187 | } 188 | }); 189 | } 190 | for (std::thread & thread : threads) 191 | { 192 | thread.join(); 193 | } 194 | } 195 | 196 | #endif 197 | 198 | #endif 199 | -------------------------------------------------------------------------------- /src/meta/typeTraits.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace meta 10 | { 11 | template 12 | struct is_pointer : std::is_pointer 13 | { 14 | }; 15 | template 16 | struct is_pointer> : std::true_type 17 | { 18 | }; 19 | template 20 | struct remove_pointer : std::remove_pointer 21 | { 22 | }; 23 | template 24 | struct remove_pointer> 25 | { 26 | typedef T type; 27 | }; 28 | 29 | template 30 | struct has_reserve 31 | { 32 | template 33 | static int check(decltype(std::declval().reserve(std::declval())) *); 34 | template 35 | static float check(...); 36 | 37 | static constexpr bool value = std::is_same(nullptr))>::value; 38 | }; 39 | 40 | template 41 | struct is_simple_type 42 | : std::integral_constant::value || std::is_fundamental::value> 43 | { 44 | }; 45 | template 46 | struct is_map_type 47 | { 48 | template 49 | static int check(typename U::key_type *, typename U::mapped_type *); 50 | template 51 | static float check(...); 52 | 53 | static constexpr bool value = std::is_same(nullptr, nullptr))>::value; 54 | }; 55 | template 56 | struct is_list_type 57 | { 58 | template 59 | static int check(typename U::value_type *); 60 | template 61 | static float check(...); 62 | 63 | static constexpr bool value = std::is_same(nullptr))>::value; 64 | }; 65 | template 66 | struct is_class_type 67 | : std::is_class 68 | { 69 | }; 70 | template 71 | struct is_pointer_to_class 72 | : std::integral_constant::value && is_class_type::type>::value> 73 | { 74 | }; 75 | 76 | namespace detail 77 | { 78 | template 79 | struct less_than_comparable_helper 80 | : std::false_type 81 | { 82 | }; 83 | template 84 | struct less_than_comparable_helper(std::declval() < std::declval()))>::type> 85 | : std::true_type 86 | { 87 | }; 88 | } 89 | 90 | template 91 | struct is_less_than_comparable 92 | : detail::less_than_comparable_helper 93 | { 94 | }; 95 | 96 | template 97 | struct is_less_than_comparable> 98 | : meta::is_less_than_comparable 99 | { 100 | }; 101 | template 102 | struct is_less_than_comparable > 103 | : std::integral_constant::value && meta::is_less_than_comparable::value> 104 | { 105 | }; 106 | 107 | namespace detail 108 | { 109 | template 110 | struct equality_comparable_helper 111 | : std::false_type 112 | { 113 | }; 114 | 115 | template 116 | struct equality_comparable_helper(std::declval() == std::declval()))>::type> 117 | : std::true_type 118 | { 119 | }; 120 | } 121 | 122 | template 123 | struct is_equality_comparable 124 | : detail::equality_comparable_helper 125 | { 126 | }; 127 | template 128 | struct is_equality_comparable> 129 | : meta::is_equality_comparable 130 | { 131 | }; 132 | template 133 | struct is_equality_comparable > 134 | : std::integral_constant::value && meta::is_equality_comparable::value> 135 | { 136 | }; 137 | 138 | namespace detail 139 | { 140 | template 141 | struct is_constructible_helper 142 | { 143 | template()))> 144 | static std::true_type test(int); 145 | 146 | template 147 | static std::false_type test(...); 148 | 149 | typedef decltype(test(0)) type; 150 | }; 151 | } 152 | 153 | template 154 | struct is_copy_constructible 155 | : detail::is_constructible_helper::type 156 | { 157 | }; 158 | template 159 | struct is_copy_constructible > 160 | : std::integral_constant::value && meta::is_copy_constructible::value> 161 | { 162 | }; 163 | template 164 | struct is_copy_constructible > 165 | : std::integral_constant::value && meta::is_copy_constructible::value> 166 | { 167 | }; 168 | template 169 | struct is_copy_constructible > 170 | : meta::is_copy_constructible 171 | { 172 | }; 173 | 174 | template 175 | struct is_move_constructible 176 | : detail::is_constructible_helper::type 177 | { 178 | }; 179 | 180 | template 181 | struct is_copy_assignable : std::is_copy_assignable 182 | { 183 | }; 184 | 185 | template 186 | struct is_copy_assignable > 187 | : std::integral_constant::value && meta::is_copy_assignable::value> 188 | { 189 | }; 190 | template 191 | struct is_copy_assignable > 192 | : std::integral_constant::value && meta::is_copy_assignable::value> 193 | { 194 | }; 195 | template 196 | struct is_copy_assignable > 197 | : meta::is_copy_assignable 198 | { 199 | }; 200 | 201 | } 202 | --------------------------------------------------------------------------------