aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 01:25:45 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-07-15 01:25:45 +0000
commit0eb739af098751fae85512ddc80e289a86f5ed82 (patch)
tree61d841dc12f982b1afaf7956176f05df58a9d98c
parent57123c8a2477a4d99cb68c53d195e9fb428dd535 (diff)
parentdc953bece52b53bac740d46d32c74be1a4cf1b7c (diff)
downloadgoogle-fruit-android12-mainline-conscrypt-release.tar.gz
Snap for 7550844 from dc953bece52b53bac740d46d32c74be1a4cf1b7c to mainline-conscrypt-releaseandroid-mainline-12.0.0_r8android-mainline-12.0.0_r25android12-mainline-conscrypt-release
Change-Id: I40d34d7035e85b1d677dbb5768b0e4f57491bd95
-rw-r--r--.gitattributes1
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml326
-rw-r--r--Android.bp28
-rw-r--r--BUILD12
-rw-r--r--CMakeLists.txt83
-rw-r--r--CONTRIBUTING.md50
-rw-r--r--METADATA8
-rw-r--r--NOTICE202
-rw-r--r--OWNERS1
-rw-r--r--appveyor.yml59
-rw-r--r--cmake-modules/FindFruit.cmake32
-rw-r--r--conanfile.py43
-rw-r--r--configuration/CMakeLists.txt2
-rw-r--r--configuration/bazel/BUILD8
-rw-r--r--configuration/bazel/always_inline_attribute.cpp7
-rw-r--r--configuration/bazel/attribute_deprecated.cpp5
-rw-r--r--configuration/bazel/build_defs.bzl103
-rw-r--r--configuration/bazel/builtin_unreachable.cpp13
-rw-r--r--configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp11
-rw-r--r--configuration/bazel/constexpr_typeid.cpp6
-rw-r--r--configuration/bazel/cxa_demangle.cpp6
-rw-r--r--configuration/bazel/declspec_deprecated.cpp5
-rw-r--r--configuration/bazel/force_inline.cpp7
-rw-r--r--configuration/bazel/fruit/impl/fruit-config-base.h70
-rw-r--r--configuration/bazel/gcc_attribute_deprecated.cpp5
-rw-r--r--configuration/bazel/has_trivial_copy.cpp5
-rw-r--r--configuration/bazel/is_trivially_copyable.cpp5
-rw-r--r--configuration/bazel/max_align_t.cpp5
-rw-r--r--configuration/bazel/msvc_assume.cpp13
-rw-r--r--configuration/bazel/std_is_trivially_copy_constructible.cpp6
-rw-r--r--configuration/bazel/std_is_trivially_copyable.cpp6
-rw-r--r--configuration/bazel/std_max_align_t.cpp5
-rw-r--r--configuration/bazel/typeid.cpp5
-rw-r--r--examples/CMakeLists.txt9
-rw-r--r--extras/bazel_root/WORKSPACE10
l---------extras/bazel_root/third_party/fruit/build1
-rw-r--r--extras/bazel_usage_example/BUILD8
-rw-r--r--extras/bazel_usage_example/WORKSPACE19
-rw-r--r--extras/bazel_usage_example/main.cpp55
-rw-r--r--extras/benchmark/boost_di_source_generator.py26
-rwxr-xr-xextras/benchmark/format_bench_results.py144
-rw-r--r--extras/benchmark/fruit_source_generator.py21
-rwxr-xr-xextras/benchmark/generate_benchmark.py44
-rw-r--r--extras/benchmark/makefile_generator.py15
-rw-r--r--extras/benchmark/new_delete_benchmark.cpp12
-rw-r--r--extras/benchmark/no_di_library_source_generator.py28
-rwxr-xr-xextras/benchmark/run_benchmarks.py162
-rw-r--r--extras/benchmark/suites/boost_di.yml22
-rw-r--r--extras/benchmark/suites/debug.yml66
-rw-r--r--extras/benchmark/suites/fruit_full.yml35
-rw-r--r--extras/benchmark/suites/fruit_mostly_full.yml20
-rw-r--r--extras/benchmark/suites/fruit_quick.yml8
-rw-r--r--extras/benchmark/suites/fruit_single.yml2
-rw-r--r--extras/benchmark/suites/simple_di_full.yml27
-rw-r--r--extras/benchmark/suites/simple_di_mostly_full.yml24
-rw-r--r--extras/benchmark/tables/fruit_internal.yml688
-rw-r--r--extras/benchmark/tables/fruit_wiki.yml339
-rw-r--r--extras/dockerfiles/.dockerignore2
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-16.049
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-17.0410
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-18.0452
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-18.109
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-19.049
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-19.1040
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-20.0441
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu-20.1040
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu_arm-16.049
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu_arm-18.0421
-rw-r--r--extras/dockerfiles/Dockerfile.ubuntu_arm-20.0422
-rw-r--r--extras/dockerfiles/common_install.sh18
-rwxr-xr-xextras/dockerfiles/rebuild_all.sh13
-rw-r--r--extras/dockerfiles/ubuntu-16.04_custom.list11
-rw-r--r--extras/dockerfiles/ubuntu-16.04_install.sh27
-rw-r--r--extras/dockerfiles/ubuntu-17.04_custom.list8
-rw-r--r--extras/dockerfiles/ubuntu-17.04_install.sh18
-rw-r--r--extras/dockerfiles/ubuntu-18.04_custom.list17
-rw-r--r--extras/dockerfiles/ubuntu-18.04_install.sh28
-rw-r--r--extras/dockerfiles/ubuntu-18.10_custom.list0
-rw-r--r--extras/dockerfiles/ubuntu-18.10_install.sh16
-rw-r--r--extras/dockerfiles/ubuntu-19.04_custom.list0
-rw-r--r--extras/dockerfiles/ubuntu-19.04_install.sh15
-rw-r--r--extras/dockerfiles/ubuntu-19.10_custom.list6
-rw-r--r--extras/dockerfiles/ubuntu-20.04_custom.list4
-rw-r--r--extras/dockerfiles/ubuntu-20.10_custom.list4
-rw-r--r--extras/dockerfiles/ubuntu_arm-16.04_install.sh15
-rw-r--r--extras/dockerfiles/ubuntu_arm-18.04_custom.list8
-rw-r--r--extras/dockerfiles/ubuntu_arm-18.04_install.sh16
-rw-r--r--extras/packaging/CMakeLists.txt8
-rw-r--r--extras/packaging/PKGBUILD2
-rw-r--r--extras/packaging/deploy_to_bintray.bat2
-rwxr-xr-xextras/packaging/deploy_to_bintray.sh2
-rw-r--r--extras/packaging/libfruit.dsc6
-rw-r--r--extras/packaging/libfruit.spec6
-rwxr-xr-xextras/scripts/postsubmit-helper.sh72
-rw-r--r--extras/scripts/postsubmit.bat1
-rwxr-xr-xextras/scripts/travis_ci_install_osx.sh37
-rwxr-xr-xextras/scripts/travis_yml_generator.py67
-rw-r--r--include/fruit/component.h25
-rw-r--r--include/fruit/component_function.h9
-rw-r--r--include/fruit/impl/component.defn.h5
-rw-r--r--include/fruit/impl/component_functors.defn.h50
-rw-r--r--include/fruit/impl/component_storage/component_storage.defn.h6
-rw-r--r--include/fruit/impl/component_storage/component_storage.h6
-rw-r--r--include/fruit/impl/component_storage/component_storage_entry.h2
-rw-r--r--include/fruit/impl/component_storage/partial_component_storage.defn.h12
-rw-r--r--include/fruit/impl/data_structures/arena_allocator.h4
-rw-r--r--include/fruit/impl/data_structures/fixed_size_allocator.defn.h6
-rw-r--r--include/fruit/impl/data_structures/fixed_size_allocator.h6
-rw-r--r--include/fruit/impl/data_structures/fixed_size_vector.defn.h4
-rw-r--r--include/fruit/impl/data_structures/fixed_size_vector.h6
-rw-r--r--include/fruit/impl/data_structures/memory_pool.defn.h4
-rw-r--r--include/fruit/impl/data_structures/memory_pool.h4
-rw-r--r--include/fruit/impl/data_structures/packed_pointer_and_bool.h4
-rw-r--r--include/fruit/impl/data_structures/semistatic_graph.h12
-rw-r--r--include/fruit/impl/data_structures/semistatic_map.h8
-rw-r--r--include/fruit/impl/injection_errors.h15
-rw-r--r--include/fruit/impl/injector/injector_storage.defn.h2
-rw-r--r--include/fruit/impl/injector/injector_storage.h3
-rw-r--r--include/fruit/impl/normalized_component_storage/binding_normalization.templates.h30
-rw-r--r--include/fruit/impl/normalized_component_storage/normalized_component_storage.h2
-rw-r--r--include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h5
-rw-r--r--include/fruit/impl/util/hash_helpers.defn.h2
-rw-r--r--include/fruit/impl/util/lambda_invoker.h16
-rw-r--r--include/fruit/impl/util/type_info.defn.h2
-rw-r--r--include/fruit/impl/util/type_info.h4
-rw-r--r--include/fruit/injector.h4
-rw-r--r--include/fruit/normalized_component.h4
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/binding_normalization.cpp28
-rw-r--r--src/fixed_size_allocator.cpp2
-rw-r--r--src/injector_storage.cpp2
-rw-r--r--src/memory_pool.cpp4
-rw-r--r--src/normalized_component_storage.cpp5
-rw-r--r--src/normalized_component_storage_holder.cpp5
-rw-r--r--src/semistatic_graph.cpp2
-rw-r--r--src/semistatic_map.cpp2
-rw-r--r--tests/BUILD25
-rw-r--r--tests/CMakeLists.txt11
-rw-r--r--tests/build_defs.bzl1
-rw-r--r--tests/data_structures/test_semistatic_graph.py20
-rw-r--r--tests/fruit_test_common.py19
-rw-r--r--tests/test_common.cpp36
-rw-r--r--tests/test_common.h25
-rwxr-xr-xtests/test_component_functions.py3
-rwxr-xr-xtests/test_normalized_component.py2
-rwxr-xr-xtests/test_register_constructor.py47
-rwxr-xr-xtests/test_register_factory.py73
-rw-r--r--tests/util/test_type_info.py2
149 files changed, 2829 insertions, 1374 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..912b302
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.py linguist-detectable=false
diff --git a/.gitignore b/.gitignore
index 128e3cd..2a2e921 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ bench_results
/*.vcxproj.filters
/CMakeSettings.json
/*.vcxproj.user
+/out/build/x64-Debug
+/out/build/x64-Debug cxx-17
+/extras/bazel_usage_example/bazel-*
diff --git a/.travis.yml b/.travis.yml
index 9e1c79f..50045e3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,44 +4,65 @@
branches:
only:
- master
-dist: trusty
+dist: xenial
language: cpp
matrix:
fast_finish: true
include:
- compiler: gcc
- env: COMPILER=gcc-9 UBUNTU=19.04 TEST=ReleasePlain
- install: export OS=linux; export COMPILER='gcc-9'; export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=gcc-10 UBUNTU=20.10 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='gcc-9'; export UBUNTU='19.04'; extras/scripts/postsubmit.sh
+ script: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/postsubmit.sh
ReleasePlain
- compiler: gcc
- env: COMPILER=gcc-9 UBUNTU=19.04 TEST=DebugPlain
- install: export OS=linux; export COMPILER='gcc-9'; export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=gcc-10 UBUNTU=20.10 TEST=DebugPlain
+ install: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='gcc-9'; export UBUNTU='19.04'; extras/scripts/postsubmit.sh
+ script: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/postsubmit.sh
DebugPlain
- compiler: clang
- env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=19.04 TEST=ReleasePlain
+ env: COMPILER=clang-8.0 STL=libstdc++ UBUNTU=20.10 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/postsubmit.sh ReleasePlain
+ - compiler: clang
+ env: COMPILER=clang-8.0 STL=libstdc++ UBUNTU=20.10 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/postsubmit.sh DebugAsanUbsan
+ - compiler: clang
+ env: COMPILER=clang-8.0 STL=libstdc++ UBUNTU=20.10 TEST=DebugPlain
+ install: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/postsubmit.sh DebugPlain
+ - compiler: clang
+ env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=20.04 TEST=ReleasePlain
install: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ export UBUNTU='20.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
script: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/postsubmit.sh ReleasePlain
+ export UBUNTU='20.04'; extras/scripts/postsubmit.sh ReleasePlain
- compiler: clang
- env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=19.04 TEST=DebugAsanUbsan
+ env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=20.04 TEST=DebugAsanUbsan
install: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ export UBUNTU='20.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
script: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/postsubmit.sh DebugAsanUbsan
+ export UBUNTU='20.04'; extras/scripts/postsubmit.sh DebugAsanUbsan
- compiler: clang
- env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=19.04 TEST=DebugPlain
+ env: COMPILER=clang-6.0 STL=libstdc++ UBUNTU=20.04 TEST=DebugPlain
install: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ export UBUNTU='20.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
script: export OS=linux; export COMPILER='clang-6.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/postsubmit.sh DebugPlain
+ export UBUNTU='20.04'; extras/scripts/postsubmit.sh DebugPlain
- compiler: gcc
env: COMPILER=bazel UBUNTU=18.04
install: export OS=linux; export COMPILER='bazel'; export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
@@ -49,101 +70,115 @@ matrix:
script: export OS=linux; export COMPILER='bazel'; export UBUNTU='18.04'; extras/scripts/postsubmit.sh
DebugPlain
- compiler: gcc
- env: COMPILER=gcc-9 TEST=DebugPlain
- install: export OS=osx; export COMPILER='gcc-9'; extras/scripts/travis_ci_install_osx.sh
- os: osx
- osx_image: xcode11.4
- script: export OS=osx; export COMPILER='gcc-9'; extras/scripts/postsubmit.sh DebugPlain
- - compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugPlain
- install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
- os: osx
- osx_image: xcode10.3
- script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugPlain
- - compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugPlain
- install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
- os: osx
- osx_image: xcode11.4
- script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugPlain
+ env: COMPILER=gcc-7 UBUNTU=20.10 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.10'; extras/scripts/postsubmit.sh
+ ReleasePlain
+ - compiler: gcc
+ env: COMPILER=gcc-7 UBUNTU=20.10 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.10'; extras/scripts/postsubmit.sh
+ DebugAsanUbsan
+ - compiler: gcc
+ env: COMPILER=gcc-10 UBUNTU=20.10 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-10'; export UBUNTU='20.10'; extras/scripts/postsubmit.sh
+ DebugAsanUbsan
- compiler: clang
- env: COMPILER=clang-8.0 STL=libstdc++ UBUNTU=19.04 TEST=ReleasePlainNoPch
- install: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-11.0 STL=libstdc++ UBUNTU=20.10 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='clang-11.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/postsubmit.sh ReleasePlainNoPch
+ script: export OS=linux; export COMPILER='clang-11.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/postsubmit.sh ReleasePlain
- compiler: clang
- env: COMPILER=clang-8.0 STL=libstdc++ UBUNTU=19.04 TEST=DebugAsanUbsanNoPch
- install: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-11.0 STL=libstdc++ UBUNTU=20.10 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='clang-11.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-8.0'; export STL='libstdc++';
- export UBUNTU='19.04'; extras/scripts/postsubmit.sh DebugAsanUbsanNoPch
+ script: export OS=linux; export COMPILER='clang-11.0'; export STL='libstdc++';
+ export UBUNTU='20.10'; extras/scripts/postsubmit.sh DebugAsanUbsan
- compiler: clang
- env: COMPILER=clang-8.0 STL=libc++ UBUNTU=19.04 TEST=ReleasePlainNoPch
- install: export OS=linux; export COMPILER='clang-8.0'; export STL='libc++'; export
- UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-11.0 STL=libc++ UBUNTU=20.10 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='clang-11.0'; export STL='libc++'; export
+ UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-8.0'; export STL='libc++'; export
- UBUNTU='19.04'; extras/scripts/postsubmit.sh ReleasePlainNoPch
+ script: export OS=linux; export COMPILER='clang-11.0'; export STL='libc++'; export
+ UBUNTU='20.10'; extras/scripts/postsubmit.sh ReleasePlain
- compiler: clang
- env: COMPILER=clang-8.0 STL=libc++ UBUNTU=19.04 TEST=DebugAsanUbsanNoPch
- install: export OS=linux; export COMPILER='clang-8.0'; export STL='libc++'; export
- UBUNTU='19.04'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-11.0 STL=libc++ UBUNTU=20.10 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='clang-11.0'; export STL='libc++'; export
+ UBUNTU='20.10'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='clang-11.0'; export STL='libc++'; export
+ UBUNTU='20.10'; extras/scripts/postsubmit.sh DebugAsanUbsan
+ - compiler: gcc
+ env: COMPILER=gcc-7 UBUNTU=20.04 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.04'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.04'; extras/scripts/postsubmit.sh
+ ReleasePlain
+ - compiler: gcc
+ env: COMPILER=gcc-7 UBUNTU=20.04 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-8.0'; export STL='libc++'; export
- UBUNTU='19.04'; extras/scripts/postsubmit.sh DebugAsanUbsanNoPch
+ script: export OS=linux; export COMPILER='gcc-7'; export UBUNTU='20.04'; extras/scripts/postsubmit.sh
+ DebugAsanUbsan
- compiler: gcc
- env: COMPILER=gcc-8 UBUNTU=18.10 TEST=ReleasePlain
- install: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=gcc-5 UBUNTU=18.04 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='gcc-5'; export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.10'; extras/scripts/postsubmit.sh
+ script: export OS=linux; export COMPILER='gcc-5'; export UBUNTU='18.04'; extras/scripts/postsubmit.sh
ReleasePlain
- compiler: gcc
- env: COMPILER=gcc-8 UBUNTU=18.10 TEST=DebugPlain
- install: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=gcc-5 UBUNTU=18.04 TEST=DebugPlain
+ install: export OS=linux; export COMPILER='gcc-5'; export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.10'; extras/scripts/postsubmit.sh
+ script: export OS=linux; export COMPILER='gcc-5'; export UBUNTU='18.04'; extras/scripts/postsubmit.sh
+ DebugPlain
+ - compiler: gcc
+ env: COMPILER=gcc-8 UBUNTU=18.04 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.04'; extras/scripts/postsubmit.sh
+ ReleasePlain
+ - compiler: gcc
+ env: COMPILER=gcc-8 UBUNTU=18.04 TEST=DebugPlain
+ install: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
+ os: linux
+ script: export OS=linux; export COMPILER='gcc-8'; export UBUNTU='18.04'; extras/scripts/postsubmit.sh
DebugPlain
- compiler: clang
- env: COMPILER=clang-4.0 STL=libstdc++ UBUNTU=18.10 TEST=ReleasePlain
- install: export OS=linux; export COMPILER='clang-4.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-3.9 STL=libstdc++ UBUNTU=18.04 TEST=ReleasePlain
+ install: export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++';
+ export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-4.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/postsubmit.sh ReleasePlain
+ script: export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++';
+ export UBUNTU='18.04'; extras/scripts/postsubmit.sh ReleasePlain
- compiler: clang
- env: COMPILER=clang-4.0 STL=libstdc++ UBUNTU=18.10 TEST=DebugAsanUbsan
- install: export OS=linux; export COMPILER='clang-4.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ env: COMPILER=clang-3.9 STL=libstdc++ UBUNTU=18.04 TEST=DebugAsanUbsan
+ install: export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++';
+ export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
- script: export OS=linux; export COMPILER='clang-4.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/postsubmit.sh DebugAsanUbsan
+ script: export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++';
+ export UBUNTU='18.04'; extras/scripts/postsubmit.sh DebugAsanUbsan
- compiler: clang
- env: COMPILER=clang-7.0 STL=libstdc++ UBUNTU=18.10 TEST=ReleasePlainNoPch
+ env: COMPILER=clang-7.0 STL=libstdc++ UBUNTU=18.04 TEST=ReleasePlainNoPch
install: export OS=linux; export COMPILER='clang-7.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
script: export OS=linux; export COMPILER='clang-7.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/postsubmit.sh ReleasePlainNoPch
+ export UBUNTU='18.04'; extras/scripts/postsubmit.sh ReleasePlainNoPch
- compiler: clang
- env: COMPILER=clang-7.0 STL=libstdc++ UBUNTU=18.10 TEST=DebugAsanUbsanNoPch
+ env: COMPILER=clang-7.0 STL=libstdc++ UBUNTU=18.04 TEST=DebugAsanUbsanNoPch
install: export OS=linux; export COMPILER='clang-7.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/travis_ci_install_linux.sh
+ export UBUNTU='18.04'; extras/scripts/travis_ci_install_linux.sh
os: linux
script: export OS=linux; export COMPILER='clang-7.0'; export STL='libstdc++';
- export UBUNTU='18.10'; extras/scripts/postsubmit.sh DebugAsanUbsanNoPch
- - compiler: gcc
- env: COMPILER=bazel UBUNTU=16.04
- install: export OS=linux; export COMPILER='bazel'; export UBUNTU='16.04'; extras/scripts/travis_ci_install_linux.sh
- os: linux
- script: export OS=linux; export COMPILER='bazel'; export UBUNTU='16.04'; extras/scripts/postsubmit.sh
- DebugPlain
+ export UBUNTU='18.04'; extras/scripts/postsubmit.sh DebugAsanUbsanNoPch
- compiler: gcc
env: COMPILER=gcc-5 UBUNTU=16.04 TEST=ReleasePlain
install: export OS=linux; export COMPILER='gcc-5'; export UBUNTU='16.04'; extras/scripts/travis_ci_install_linux.sh
@@ -185,122 +220,109 @@ matrix:
script: export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++';
export UBUNTU='16.04'; extras/scripts/postsubmit.sh DebugPlain
- compiler: gcc
- env: COMPILER=gcc-6 TEST=ReleasePlain
- install: export OS=osx; export COMPILER='gcc-6'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=gcc-6 TEST=ReleasePlainNoClangTidy
+ install: export OS=osx; export COMPILER='gcc-6'; travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='gcc-6'; extras/scripts/postsubmit.sh ReleasePlain
+ script: export OS=osx; export COMPILER='gcc-6'; extras/scripts/postsubmit.sh ReleasePlainNoClangTidy
- compiler: gcc
- env: COMPILER=gcc-6 TEST=DebugPlain
- install: export OS=osx; export COMPILER='gcc-6'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=gcc-6 TEST=DebugPlainNoClangTidy
+ install: export OS=osx; export COMPILER='gcc-6'; travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='gcc-6'; extras/scripts/postsubmit.sh DebugPlain
+ script: export OS=osx; export COMPILER='gcc-6'; extras/scripts/postsubmit.sh DebugPlainNoClangTidy
- compiler: gcc
- env: COMPILER=gcc-9 TEST=ReleasePlain
- install: export OS=osx; export COMPILER='gcc-9'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=gcc-9 TEST=ReleasePlainNoPchNoClangTidy
+ install: export OS=osx; export COMPILER='gcc-9'; travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='gcc-9'; extras/scripts/postsubmit.sh ReleasePlain
- - compiler: clang
- env: COMPILER=clang-4.0 STL=libc++ TEST=ReleasePlain
- install: export OS=osx; export COMPILER='clang-4.0'; export STL='libc++'; extras/scripts/travis_ci_install_osx.sh
+ script: export OS=osx; export COMPILER='gcc-9'; extras/scripts/postsubmit.sh ReleasePlainNoPchNoClangTidy
+ - compiler: gcc
+ env: COMPILER=gcc-9 TEST=DebugPlainNoPchNoClangTidy
+ install: export OS=osx; export COMPILER='gcc-9'; travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='clang-4.0'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlain
+ script: export OS=osx; export COMPILER='gcc-9'; extras/scripts/postsubmit.sh DebugPlainNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-4.0 STL=libc++ TEST=DebugAsanUbsan
- install: export OS=osx; export COMPILER='clang-4.0'; export STL='libc++'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=clang-6.0 STL=libc++ TEST=ReleasePlainNoClangTidy
+ install: export OS=osx; export COMPILER='clang-6.0'; export STL='libc++'; travis_wait
+ extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='clang-4.0'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsanUbsan
+ script: export OS=osx; export COMPILER='clang-6.0'; export STL='libc++'; extras/scripts/postsubmit.sh
+ ReleasePlainNoClangTidy
- compiler: clang
- env: COMPILER=clang-8.0 STL=libc++ TEST=ReleasePlainNoPch
- install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=clang-6.0 STL=libc++ TEST=DebugAsanUbsanNoClangTidy
+ install: export OS=osx; export COMPILER='clang-6.0'; export STL='libc++'; travis_wait
+ extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
- script: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlainNoPch
+ script: export OS=osx; export COMPILER='clang-6.0'; export STL='libc++'; extras/scripts/postsubmit.sh
+ DebugAsanUbsanNoClangTidy
- compiler: clang
- env: COMPILER=clang-8.0 STL=libc++ TEST=DebugAsanUbsanNoPch
- install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=clang-8.0 STL=libc++ TEST=ReleasePlainNoPchNoClangTidy
+ install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; travis_wait
+ extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
script: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsanUbsanNoPch
+ ReleasePlainNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-8.0 STL=libc++ TEST=DebugPlainNoPch
- install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/travis_ci_install_osx.sh
+ env: COMPILER=clang-8.0 STL=libc++ TEST=DebugAsanUbsanNoPchNoClangTidy
+ install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; travis_wait
+ extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode11.4
script: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugPlainNoPch
+ DebugAsanUbsanNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=ReleasePlain
- install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
+ env: COMPILER=clang-8.0 STL=libc++ TEST=DebugPlainNoPchNoClangTidy
+ install: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; travis_wait
extras/scripts/travis_ci_install_osx.sh
os: osx
- osx_image: xcode8.3
- script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlain
- - compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugAsan
- install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
- os: osx
- osx_image: xcode8.3
- script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsan
+ osx_image: xcode11.4
+ script: export OS=osx; export COMPILER='clang-8.0'; export STL='libc++'; extras/scripts/postsubmit.sh
+ DebugPlainNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=ReleasePlain
+ env: COMPILER=clang-default STL=libc++ TEST=ReleasePlainNoClangTidy
install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
+ travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode9.4
script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlain
+ ReleasePlainNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugAsanUbsan
+ env: COMPILER=clang-default STL=libc++ TEST=DebugAsanUbsanNoClangTidy
install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
+ travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
osx_image: xcode9.4
script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsanUbsan
+ DebugAsanUbsanNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=ReleasePlain
+ env: COMPILER=clang-default STL=libc++ TEST=ReleasePlainNoPchNoClangTidy
install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
+ travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
- osx_image: xcode10.3
+ osx_image: xcode11.3
script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlain
+ ReleasePlainNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugAsanUbsan
+ env: COMPILER=clang-default STL=libc++ TEST=DebugAsanUbsanNoPchNoClangTidy
install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
+ travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
- osx_image: xcode10.3
+ osx_image: xcode11.3
script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsanUbsan
+ DebugAsanUbsanNoPchNoClangTidy
- compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=ReleasePlain
+ env: COMPILER=clang-default STL=libc++ TEST=DebugPlainNoPchNoClangTidy
install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
+ travis_wait extras/scripts/travis_ci_install_osx.sh
os: osx
- osx_image: xcode11.4
+ osx_image: xcode11.3
script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- ReleasePlain
- - compiler: clang
- env: COMPILER=clang-default STL=libc++ TEST=DebugAsanUbsan
- install: export OS=osx; export COMPILER='clang-default'; export STL='libc++';
- extras/scripts/travis_ci_install_osx.sh
- os: osx
- osx_image: xcode11.4
- script: export OS=osx; export COMPILER='clang-default'; export STL='libc++'; extras/scripts/postsubmit.sh
- DebugAsanUbsan
+ DebugPlainNoPchNoClangTidy
services:
- docker
sudo: required
diff --git a/Android.bp b/Android.bp
index 9907842..444c19c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,11 +14,39 @@
// Simply '#include <fruit/fruit.h>' to get started.
// See https://github.com/google/fruit/wiki for more details.
+package {
+ default_applicable_licenses: ["external_google-fruit_license"],
+}
+
+// Added automatically by a large-scale-change
+//
+// large-scale-change included anything that looked like it might be a license
+// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
+//
+// Please consider removing redundant or irrelevant files from 'license_text:'.
+// See: http://go/android-license-faq
+license {
+ name: "external_google-fruit_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "COPYING",
+ "LICENSE",
+ ],
+}
+
cc_library {
name: "libfruit",
host_supported: true,
+ vendor_available: true,
export_include_dirs: ["include", "configuration/android"],
srcs: ["src/**/*.cpp", ],
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
}
// TODO: tests written in python+pytest that calls back into compiler. unclear how to best proceed.
diff --git a/BUILD b/BUILD
index 463ddc9..d93719c 100644
--- a/BUILD
+++ b/BUILD
@@ -6,8 +6,9 @@ filegroup(
name = "fruit_headers",
srcs = glob([
"include/**/*.h",
- "configuration/bazel/**/*.h",
- ]),
+ ]) + [
+ "//third_party/fruit/configuration/bazel:fruit-config-base",
+ ],
)
cc_library(
@@ -15,9 +16,12 @@ cc_library(
srcs = glob([
"src/*.cpp",
"include/fruit/impl/**/*.h",
- "configuration/bazel/**/*.h"]),
+ ]),
hdrs = glob(["include/fruit/*.h"]),
includes = ["include", "configuration/bazel"],
- deps = [],
+ deps = [
+ "@boost//:unordered",
+ "//third_party/fruit/configuration/bazel:fruit-config-base",
+ ],
linkopts = ["-lm"],
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20e5ba0..7efcf7b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,22 @@
-project(Fruit)
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.2)
+
+project(Fruit VERSION 3.6.0 LANGUAGES CXX)
+
+set(FRUIT_IS_BEING_BUILT_BY_CONAN FALSE CACHE BOOL "This is set in Conan builds.")
+if("${FRUIT_IS_BEING_BUILT_BY_CONAN}")
+ include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+ conan_basic_setup()
+endif()
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif()
+if ("${CMAKE_CXX_STANDARD}" STREQUAL "")
+ set(CMAKE_CXX_STANDARD 11)
+endif()
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
# CMake on OSX likes to see this set explicitly, otherwise it outputs a warning.
set(CMAKE_MACOSX_RPATH 1)
@@ -17,10 +29,6 @@ option(BUILD_SHARED_LIBS "Build shared library" ON)
# The Visual Studio CMake generators default to multiple configurations, but Fruit doesn't support multi-configuration build directories.
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}")
-if(NOT "${RUNTIME_OUTPUT_DIRECTORY}")
- set(RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
-endif()
-
set(FRUIT_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX compiler flags." FORCE)
set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_CXX_FLAGS}")
@@ -43,7 +51,8 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(MSVC)$")
# The warning C4577 is disabled because we don't need a termination guarantee on exceptions for functions marked with
# 'noexcept'.
# The warning C4530 is disabled because it's triggered by MSVC's STL.
- set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} /nologo /FS /W4 /wd4324 /wd4709 /wd4459 /wd4141 /wd4714 /wd4577 /wd4530 /D_SCL_SECURE_NO_WARNINGS")
+ # The warning C5205 is disabled, MSVC emits it for abstract classes in example code with non-virtual destructors, but we never call delete on those (even though std::default_delete<Scaler> is instantiated for those types).
+ set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} /nologo /FS /W4 /wd4324 /wd4709 /wd4459 /wd4141 /wd4714 /wd4577 /wd4530 /wd5205 /D_SCL_SECURE_NO_WARNINGS")
endif()
option(FRUIT_ENABLE_COVERAGE "Enable collection of test coverage. This is meant to be used by Fruit developers. It's only supported when using GCC on Linux." OFF)
@@ -58,14 +67,19 @@ set(FRUIT_USES_BOOST TRUE CACHE BOOL
"Whether to use Boost (specifically, boost::unordered_set and boost::unordered_map).
If this is false, Fruit will use std::unordered_set and std::unordered_map instead (however this causes injection to be a bit slower).")
-set(FRUIT_IS_BEING_BUILT_BY_CONAN FALSE CACHE BOOL "This is set in Conan builds.")
+if(${FRUIT_USES_BOOST})
-if("${WIN32}" AND "${FRUIT_USES_BOOST}" AND NOT "${FRUIT_IS_BEING_BUILT_BY_CONAN}")
- set(BOOST_DIR "" CACHE PATH "The directory where the boost library is installed, e.g. C:\\boost\\boost_1_62_0.")
- if("${BOOST_DIR}" STREQUAL "")
- message(FATAL_ERROR "Please re-run CMake, specifying the boost library path as BOOST_DIR, e.g. -DBOOST_DIR=C:\\boost\\boost_1_62_0, or specify -DFRUIT_USES_BOOST=False to not use boost.")
+ if(DEFINED BOOST_DIR)
+ message(DEPRECATION "BOOST_DIR is deprecated. Use Boost_INCLUDE_DIR instead.")
+ set(Boost_INCLUDE_DIR "${BOOST_DIR}" CACHE PATH "")
+ endif()
+
+ find_package(Boost)
+ if(Boost_FOUND)
+ include_directories(${Boost_INCLUDE_DIRS})
+ else()
+ message(FATAL_ERROR "Please re-run CMake, specifying the boost library path as Boost_INCLUDE_DIR, e.g. -DBoost_INCLUDE_DIR=C:\\boost\\boost_1_62_0, or specify -DFRUIT_USES_BOOST=False to not use boost.")
endif()
- include_directories("${BOOST_DIR}")
endif()
set(RUN_TESTS_UNDER_VALGRIND FALSE CACHE BOOL "Whether to run Fruit tests under valgrind")
@@ -87,6 +101,18 @@ else()
set(FRUIT_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${FRUIT_ADDITIONAL_COMPILE_FLAGS}")
endif()
+set(FRUIT_CLANG_TIDY_CHECKS
+ bugprone*,-bugprone-reserved-identifier,-bugprone-exception-escape,clang-analyzer*,performance*,google*,-google-readability*,-google-runtime-references,clang-diagnostic-unused-command-line-argument,misc-macro-parentheses,-clang-diagnostic-dtor-name)
+
+set(FRUIT_ENABLE_CLANG_TIDY FALSE CACHE BOOL "Whether to run clang-tidy on the Fruit codebase during the build")
+if(${FRUIT_ENABLE_CLANG_TIDY})
+ set(CMAKE_CXX_CLANG_TIDY
+ clang-tidy;
+ -header-filter=fruit;
+ -checks=${FRUIT_CLANG_TIDY_CHECKS};
+ -warnings-as-errors=*;)
+endif()
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
@@ -94,34 +120,29 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
# of the user-friendly default that hides Fruit internals).
#add_definitions(-DFRUIT_DEEP_TEMPLATE_INSTANTIATION_STACKTRACES_FOR_ERRORS=1)
-set(INSTALL_INCLUDE_DIR include/fruit CACHE PATH "Installation directory for headers")
-set(INSTALL_LIBRARY_DIR lib CACHE PATH "Installation directory for libraries")
-
-set(FRUIT_VERSION "3.4.0")
+include(GNUInstallDirs)
add_subdirectory(configuration)
add_subdirectory(src)
-if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
- # Do not exclude these from "make all" in debug mode, they must build.
- add_subdirectory(examples)
- add_subdirectory(tests)
-else()
- add_subdirectory(examples EXCLUDE_FROM_ALL)
- add_subdirectory(tests)
-endif()
+if(NOT "${FRUIT_IS_BEING_BUILT_BY_CONAN}")
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+ # Do not exclude these from "make all" in debug mode, they must build.
+ add_subdirectory(examples)
+ add_subdirectory(tests)
+ else()
+ add_subdirectory(examples EXCLUDE_FROM_ALL)
+ add_subdirectory(tests)
+ endif()
-add_subdirectory(extras EXCLUDE_FROM_ALL)
+ add_subdirectory(extras EXCLUDE_FROM_ALL)
+endif()
install(DIRECTORY include/fruit/
- DESTINATION "${INSTALL_INCLUDE_DIR}"
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fruit
FILES_MATCHING PATTERN "*.h")
set(CPACK_PACKAGE_NAME "Fruit")
set(CPACK_PACKAGE_VENDOR "Marco Poletti")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fruit - Dependency Injection Framework For C++")
-string(REGEX REPLACE "([^.]*)\\.([^.]*)\\.([^.]*)" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${FRUIT_VERSION}")
-string(REGEX REPLACE "([^.]*)\\.([^.]*)\\.([^.]*)" "\\2" CPACK_PACKAGE_VERSION_MINOR "${FRUIT_VERSION}")
-string(REGEX REPLACE "([^.]*)\\.([^.]*)\\.([^.]*)" "\\3" CPACK_PACKAGE_VERSION_PATCH "${FRUIT_VERSION}")
-set(CPACK_PACKAGE_VERSION "${FRUIT_VERSION}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Fruit")
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 89a3fca..1415516 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -27,7 +27,7 @@ Example commands to build a development version of Fruit using CMake (with all a
cd $PATH_TO_FRUIT
mkdir build-debug
cd build-debug
-cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-Werror -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1"
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="-Werror -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1"
make -j 16
cd tests
py.test-3 -n auto
@@ -104,43 +104,30 @@ For example, if you installed Boost in `C:\boost\boost_1_62_0`, you can put this
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
{
- "name": "x86-Debug",
- "generator": "Visual Studio 15 2017",
- "configurationType": "Debug",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
- "buildCommandArgs": "-m -v:minimal"
+ "name": "x64-Debug",
+ "generator": "Visual Studio 16 2019 Win64",
+ "configurationType": "Debug",
+ "buildRoot": "${projectDir}\\out\\build\\${name}",
+ "cmakeCommandArgs": "-DBoost_INCLUDE_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
+ "buildCommandArgs": "-m -v:minimal",
+ "intelliSenseMode": "windows-msvc-x64"
},
{
- "name": "x86-Release",
- "generator": "Visual Studio 15 2017",
- "configurationType": "Release",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Release",
- "buildCommandArgs": "-m -v:minimal"
- },
- {
- "name": "x64-Debug",
- "generator": "Visual Studio 15 2017 Win64",
- "configurationType": "Debug",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
- "buildCommandArgs": "-m -v:minimal"
- },
- {
- "name": "x64-Release",
- "generator": "Visual Studio 15 2017 Win64",
- "configurationType": "Release",
- "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
- "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Release",
- "buildCommandArgs": "-m -v:minimal"
+ "name": "x64-Debug-noboost",
+ "generator": "Visual Studio 16 2019 Win64",
+ "configurationType": "Debug",
+ "buildRoot": "${projectDir}\\out\\build\\${name}",
+ "cmakeCommandArgs": "-DFRUIT_USES_BOOST=False -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
+ "buildCommandArgs": "-m -v:minimal",
+ "intelliSenseMode": "windows-msvc-x64"
}
+
]
}
The `/Z7` flag instructs Visual Studio to use the C7 format for debugging information, which allows Fruit's tests to run in parallel without interfering with each other.
-If you don't want to use Boost, you can replace the `-DBOOST_DIR=...` flags above with `-DFRUIT_USES_BOOST=False`.
+If you don't want to use Boost, you can replace the `-DBoost_INCLUDE_DIR=...` flags above with `-DFRUIT_USES_BOOST=False`.
You can now run CMake within Visual Studio (from the menu: CMake -> Cache -> Generate -> CMakeLists.txt) and build Fruit (from the menu: CMake -> Build All).
@@ -148,8 +135,9 @@ You can also run tests, but *only* from the command-line (after building Fruit f
To do that, you'll need python3 installed (you can download it [here](https://www.python.org/downloads/)).
-You'll also the `pytest` and `pytest-xdist` packages. You can install them with:
+You'll also some Python packages. You can install them with:
+ pip install absl-py
pip install pytest
pip install pytest-xdist
diff --git a/METADATA b/METADATA
index 2b61d1b..d1e2e35 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/google/fruit.git"
}
- version: "bb1fc3b3abe3eda0f093fb1d45f9be96c6af6366"
+ version: "70f7c06e305ad7c9e4e99b87672aaa1061d914d6"
license_type: NOTICE
last_upgrade_date {
- year: 2019
- month: 9
- day: 3
+ year: 2020
+ month: 11
+ day: 30
}
}
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 80d612b..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 2014 Google Inc. All rights reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/OWNERS b/OWNERS
index 32bf1c3..650f1d9 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1,2 @@
+hhb@google.com
iam@google.com
diff --git a/appveyor.yml b/appveyor.yml
index bc9a449..2406142 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,23 +3,48 @@ clone_folder: C:\Fruit
environment:
PYTHON3_PATH: C:\Python36
matrix:
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- CMAKE_GENERATOR: 'Visual Studio 14 2015 Win64'
- VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC'
- ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX /DFRUIT_DEBUG /DFRUIT_EXTRA_DEBUG /D_ITERATOR_DEBUG_LEVEL=2" -T host=x64'
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ CMAKE_GENERATOR: 'Visual Studio 16 2019'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX /DFRUIT_DEBUG /DFRUIT_EXTRA_DEBUG /D_ITERATOR_DEBUG_LEVEL=2" -T host=x64 -A x64 -DCMAKE_CXX_STANDARD=17'
+ CONFIGURATION: Debug
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ CMAKE_GENERATOR: 'Visual Studio 16 2019'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX /DFRUIT_DEBUG /DFRUIT_EXTRA_DEBUG /D_ITERATOR_DEBUG_LEVEL=2" -T host=x64 -A x64'
CONFIGURATION: Debug
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: 'Visual Studio 15 2017 Win64'
VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build'
ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX /DFRUIT_DEBUG /DFRUIT_EXTRA_DEBUG /D_ITERATOR_DEBUG_LEVEL=2" -T host=x64'
CONFIGURATION: Debug
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ CMAKE_GENERATOR: 'Visual Studio 16 2019'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64 -A x64'
+ CONFIGURATION: Release
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ CMAKE_GENERATOR: 'Visual Studio 15 2017 Win64'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
+ CONFIGURATION: Release
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ CMAKE_GENERATOR: 'Visual Studio 16 2019'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64 -A x64'
+ CONFIGURATION: Release
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ CMAKE_GENERATOR: 'Visual Studio 15 2017 Win64'
+ VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build'
+ ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
+ CONFIGURATION: Release
+
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MINGW_PATH: 'C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin'
CMAKE_GENERATOR: 'MinGW Makefiles'
VCVARSALL_DIR: ''
ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="-Werror -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1"'
CONFIGURATION: Debug
-
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MINGW_PATH: 'C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin'
CMAKE_GENERATOR: 'MinGW Makefiles'
@@ -30,33 +55,13 @@ environment:
MINGW_PATH: 'C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin'
CMAKE_GENERATOR: 'MinGW Makefiles'
VCVARSALL_DIR: ''
- ADDITIONAL_CMAKE_ARGS: '-DBOOST_DIR=C:\Libraries\boost_1_64_0 -DCMAKE_CXX_FLAGS="-Werror"'
- CONFIGURATION: Release
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- CMAKE_GENERATOR: 'Visual Studio 15 2017 Win64'
- VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build'
- ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
- CONFIGURATION: Release
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- CMAKE_GENERATOR: 'Visual Studio 14 2015 Win64'
- VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC'
- ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
+ ADDITIONAL_CMAKE_ARGS: '-DBoost_INCLUDE_DIR=C:\Libraries\boost_1_69_0 -DCMAKE_CXX_FLAGS="-Werror"'
CONFIGURATION: Release
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
MINGW_PATH: 'C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin'
CMAKE_GENERATOR: 'MinGW Makefiles'
VCVARSALL_DIR: ''
- ADDITIONAL_CMAKE_ARGS: '-DBOOST_DIR=C:\Libraries\boost_1_64_0 -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="-Werror"'
- CONFIGURATION: Release
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- CMAKE_GENERATOR: 'Visual Studio 15 2017 Win64'
- VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build'
- ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
- CONFIGURATION: Release
- - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- CMAKE_GENERATOR: 'Visual Studio 14 2015 Win64'
- VCVARSALL_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC'
- ADDITIONAL_CMAKE_ARGS: '-DFRUIT_USES_BOOST=False -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="/WX" -T host=x64'
+ ADDITIONAL_CMAKE_ARGS: '-DBoost_INCLUDE_DIR=C:\Libraries\boost_1_69_0 -DBUILD_SHARED_LIBS=False -DCMAKE_CXX_FLAGS="-Werror"'
CONFIGURATION: Release
build_script:
- cmd: cmd /c C:\Fruit\extras\scripts\postsubmit.bat
diff --git a/cmake-modules/FindFruit.cmake b/cmake-modules/FindFruit.cmake
index a6155cd..3b4fc24 100644
--- a/cmake-modules/FindFruit.cmake
+++ b/cmake-modules/FindFruit.cmake
@@ -2,23 +2,23 @@
# set(ENV{FRUIT_INSTALLED_DIR} "/path/to/fruit/build")
find_path(FRUIT_INCLUDE_DIR fruit.h
- HINTS (
- FRUIT_INSTALLED_DIR
- /usr
- /usr/local
- )
- PATH_SUFFIXES include/fruit include fruit
-)
+ HINTS (
+ ${FRUIT_INSTALLED_DIR}
+ /usr
+ /usr/local
+ )
+ PATH_SUFFIXES include/fruit
+ )
find_library(FRUIT_LIBRARY
- NAMES fruit
- HINTS (
- FRUIT_INSTALLED_DIR
- /usr
- /usr/local
- )
- PATH_SUFFIXES lib ${FRUIT_INSTALLED_DIR}
-)
+ NAMES fruit
+ HINTS (
+ ${FRUIT_INSTALLED_DIR}
+ /usr
+ /usr/local
+ )
+ PATH_SUFFIXES lib lib64
+ )
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(fruit DEFAULT_MSG FRUIT_LIBRARY FRUIT_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Fruit DEFAULT_MSG FRUIT_LIBRARY FRUIT_INCLUDE_DIR)
diff --git a/conanfile.py b/conanfile.py
index 46bd1ce..a96d39c 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -5,7 +5,7 @@ import os
class FruitConan(ConanFile):
name = "fruit"
- version = "3.4.0"
+ version = "3.6.0"
license = "Apache"
url = "https://github.com/google/fruit"
homepage = "https://github.com/google/fruit"
@@ -16,6 +16,7 @@ class FruitConan(ConanFile):
generators = "cmake"
exports = "COPYING"
_source_subfolder = "source_subfolder"
+ _cmake = None
def configure(self):
min_version = {
@@ -32,37 +33,30 @@ class FruitConan(ConanFile):
self.settings.compiler.version,
min_version))
- def requirements(self):
+ def build_requirements(self):
if self.options.use_boost:
- self.requires("boost/1.68.0@conan/stable")
+ self.build_requires("boost/1.68.0@conan/stable")
def source(self):
tools.get("{0}/archive/v{1}.tar.gz".format(self.homepage, self.version))
extracted_dir = self.name + "-" + self.version
os.rename(extracted_dir, self._source_subfolder)
- # This small hack might be useful to guarantee proper /MT /MD linkage
- # in MSVC if the packaged project doesn't have variables to set it
- # properly
- tools.replace_in_file(os.path.join(self._source_subfolder, "CMakeLists.txt"),
- "project(Fruit)",
- '''PROJECT(Myfruit)
-include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
-conan_basic_setup()''')
def _configure_cmake(self):
- cmake = CMake(self)
- cmake.definitions["FRUIT_IS_BEING_BUILT_BY_CONAN"] = "YES"
- cmake.definitions["BUILD_SHARED_LIBS"] = "YES" if self.options.shared else "NO"
- if self.options.use_boost:
+ if not self._cmake:
+ self._cmake = CMake(self)
+ self._cmake.definitions["FRUIT_IS_BEING_BUILT_BY_CONAN"] = "YES"
+ self._cmake.definitions["BUILD_SHARED_LIBS"] = "YES" if self.options.shared else "NO"
+ self._cmake.definitions["FRUIT_USES_BOOST"] = self.options.use_boost
+ if self.options.use_boost:
+ self._cmake.definitions["Boost_INCLUDE_DIR"] = os.path.join(
+ self.deps_cpp_info["boost"].rootpath, "include")
if self.settings.os == "Windows":
- cmake.definitions["BOOST_DIR"] = "."
- else:
- cmake.definitions["FRUIT_USES_BOOST"] = "NO"
- if self.settings.os == "Windows":
- cmake.definitions["FRUIT_TESTS_USE_PRECOMPILED_HEADERS"] = "NO"
- cmake.definitions["CMAKE_BUILD_TYPE"] = self.settings.build_type
- cmake.configure(source_folder=self._source_subfolder)
- return cmake
+ self._cmake.definitions["FRUIT_TESTS_USE_PRECOMPILED_HEADERS"] = "NO"
+ self._cmake.definitions["CMAKE_BUILD_TYPE"] = self.settings.build_type
+ self._cmake.configure(source_folder=self._source_subfolder)
+
+ return self._cmake
def build(self):
cmake = self._configure_cmake()
@@ -76,5 +70,4 @@ conan_basic_setup()''')
src=self._source_subfolder)
def package_info(self):
- self.cpp_info.includedirs = ["include"]
- self.cpp_info.libs = ["fruit"]
+ self.cpp_info.libs = tools.collect_libs(self)
diff --git a/configuration/CMakeLists.txt b/configuration/CMakeLists.txt
index b18a463..11d8445 100644
--- a/configuration/CMakeLists.txt
+++ b/configuration/CMakeLists.txt
@@ -218,4 +218,4 @@ endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fruit-config-base.h.in ${CMAKE_CURRENT_BINARY_DIR}/../include/fruit/impl/fruit-config-base.h)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../include/fruit/impl/fruit-config-base.h
- DESTINATION ${INSTALL_INCLUDE_DIR}/impl)
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fruit/impl)
diff --git a/configuration/bazel/BUILD b/configuration/bazel/BUILD
new file mode 100644
index 0000000..a207462
--- /dev/null
+++ b/configuration/bazel/BUILD
@@ -0,0 +1,8 @@
+load("//third_party/fruit/configuration/bazel:build_defs.bzl", "generate_fruit_config")
+
+package(default_visibility = ["//third_party/fruit:__subpackages__"])
+
+generate_fruit_config(
+ name = "fruit-config-base",
+ check_sources = glob(["*.cpp"])
+)
diff --git a/configuration/bazel/always_inline_attribute.cpp b/configuration/bazel/always_inline_attribute.cpp
new file mode 100644
index 0000000..e6215af
--- /dev/null
+++ b/configuration/bazel/always_inline_attribute.cpp
@@ -0,0 +1,7 @@
+__attribute__((always_inline))
+void f() {
+}
+
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/attribute_deprecated.cpp b/configuration/bazel/attribute_deprecated.cpp
new file mode 100644
index 0000000..245519d
--- /dev/null
+++ b/configuration/bazel/attribute_deprecated.cpp
@@ -0,0 +1,5 @@
+[[deprecated]] void f();
+
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/build_defs.bzl b/configuration/bazel/build_defs.bzl
new file mode 100644
index 0000000..28c3b17
--- /dev/null
+++ b/configuration/bazel/build_defs.bzl
@@ -0,0 +1,103 @@
+load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
+load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain")
+
+def _generate_fruit_config_impl(ctx):
+ cc_toolchain = find_cpp_toolchain(ctx)
+
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
+ requested_features = ctx.features,
+ unsupported_features = ctx.disabled_features,
+ )
+ c_compiler_path = cc_common.get_tool_for_action(
+ feature_configuration = feature_configuration,
+ action_name = C_COMPILE_ACTION_NAME,
+ )
+
+ check_output_files = []
+ for check_source in ctx.files.check_sources:
+ check_name = check_source.path[:-len(".cpp")].split('/')[-1].split('\\')[-1]
+
+ output_file = ctx.actions.declare_file(check_name + ".o")
+
+ c_compile_variables = cc_common.create_compile_variables(
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts,
+ source_file = check_source.path,
+ output_file = output_file.path,
+ )
+ command_line = cc_common.get_memory_inefficient_command_line(
+ feature_configuration = feature_configuration,
+ action_name = C_COMPILE_ACTION_NAME,
+ variables = c_compile_variables,
+ )
+ env = cc_common.get_environment_variables(
+ feature_configuration = feature_configuration,
+ action_name = C_COMPILE_ACTION_NAME,
+ variables = c_compile_variables,
+ )
+
+ check_define = 'FRUIT_HAS_%s' % check_name.upper()
+ check_output_file = ctx.actions.declare_file(check_name + ".h")
+
+ ctx.actions.run_shell(
+ command = '"$@" &>/dev/null && echo "#define %s 1" >"%s" || echo "#define %s 0" >"%s"; touch "%s"' % (
+ check_define, check_output_file.path, check_define, check_output_file.path, output_file.path
+ ),
+ arguments = [c_compiler_path] + command_line,
+ env = env,
+ inputs = depset(
+ [check_source],
+ transitive = [cc_toolchain.all_files],
+ ),
+ outputs = [output_file, check_output_file],
+ )
+ check_output_files.append(check_output_file)
+
+ merged_output_file = ctx.actions.declare_file("fruit/impl/fruit-config-base.h")
+ ctx.actions.run_shell(
+ command = '\n'.join([
+ '(',
+ 'echo "#ifndef FRUIT_CONFIG_BASE_H"',
+ 'echo "#define FRUIT_CONFIG_BASE_H"',
+ 'echo "#define FRUIT_USES_BOOST 1"',
+ 'cat %s' % ' '.join([check_output_file.path for check_output_file in check_output_files]),
+ 'echo "#endif"',
+ ')>%s' % merged_output_file.path
+ ]),
+ inputs = check_output_files,
+ outputs = [merged_output_file],
+ )
+
+ compilation_context, compilation_outputs = cc_common.compile(
+ actions = ctx.actions,
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ public_hdrs = [merged_output_file],
+ name = "%s_link" % ctx.label.name,
+ )
+
+ linking_context, linking_outputs = cc_common.create_linking_context_from_compilation_outputs(
+ actions = ctx.actions,
+ feature_configuration = feature_configuration,
+ compilation_outputs = compilation_outputs,
+ cc_toolchain = cc_toolchain,
+ name = "%s_link" % ctx.label.name,
+ )
+
+ return [
+ DefaultInfo(files = depset([merged_output_file]), runfiles = ctx.runfiles(files = [merged_output_file])),
+ CcInfo(compilation_context=compilation_context, linking_context=linking_context),
+ ]
+
+generate_fruit_config = rule(
+ implementation = _generate_fruit_config_impl,
+ attrs = {
+ "check_sources": attr.label_list(allow_files = True),
+ "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
+ },
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+ fragments = ["cpp"],
+) \ No newline at end of file
diff --git a/configuration/bazel/builtin_unreachable.cpp b/configuration/bazel/builtin_unreachable.cpp
new file mode 100644
index 0000000..11d20cf
--- /dev/null
+++ b/configuration/bazel/builtin_unreachable.cpp
@@ -0,0 +1,13 @@
+int f() {
+ static int x = 1;
+ if (x == 1) {
+ return 0;
+ } else {
+ __builtin_unreachable();
+ // Note: the lack of return here is intentional
+ }
+}
+
+int main() {
+ return f();
+}
diff --git a/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp b/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp
new file mode 100644
index 0000000..67b4317
--- /dev/null
+++ b/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp
@@ -0,0 +1,11 @@
+template <typename T, typename U>
+struct Pair {};
+
+struct Map : public Pair<int, float>, Pair<int, char> {};
+
+template <typename Value>
+Value f(Pair<int, Value>*) { return Value(); }
+
+int main() {
+ f((Map*)0);
+}
diff --git a/configuration/bazel/constexpr_typeid.cpp b/configuration/bazel/constexpr_typeid.cpp
new file mode 100644
index 0000000..a793377
--- /dev/null
+++ b/configuration/bazel/constexpr_typeid.cpp
@@ -0,0 +1,6 @@
+#include <typeinfo>
+int main() {
+ constexpr static const std::type_info& x = typeid(int);
+ (void) x;
+ return 0;
+}
diff --git a/configuration/bazel/cxa_demangle.cpp b/configuration/bazel/cxa_demangle.cpp
new file mode 100644
index 0000000..3e4f57f
--- /dev/null
+++ b/configuration/bazel/cxa_demangle.cpp
@@ -0,0 +1,6 @@
+#include <cxxabi.h>
+int main() {
+ auto* p = abi::__cxa_demangle;
+ (void) p;
+ return 0;
+}
diff --git a/configuration/bazel/declspec_deprecated.cpp b/configuration/bazel/declspec_deprecated.cpp
new file mode 100644
index 0000000..79a9f43
--- /dev/null
+++ b/configuration/bazel/declspec_deprecated.cpp
@@ -0,0 +1,5 @@
+__declspec(deprecated) void f();
+
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/force_inline.cpp b/configuration/bazel/force_inline.cpp
new file mode 100644
index 0000000..fab42d2
--- /dev/null
+++ b/configuration/bazel/force_inline.cpp
@@ -0,0 +1,7 @@
+__forceinline
+void f() {
+}
+
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/fruit/impl/fruit-config-base.h b/configuration/bazel/fruit/impl/fruit-config-base.h
deleted file mode 100644
index 8e7af1d..0000000
--- a/configuration/bazel/fruit/impl/fruit-config-base.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef FRUIT_CONFIG_BASE_H
-#define FRUIT_CONFIG_BASE_H
-
-// Needed for all Clang versions (as of January 2016), not needed for GCC.
-// This can also be defined for GCC, but it slightly slows down compile time of code using Fruit.
-#define FRUIT_HAS_CLANG_ARBITRARY_OVERLOAD_RESOLUTION_BUG 1
-
-// Whether the compiler defines std::max_align_t.
-#define FRUIT_HAS_STD_MAX_ALIGN_T 1
-
-// Whether the compiler defines ::max_align_t.
-// Ignored if FRUIT_HAS_STD_MAX_ALIGN_T is set.
-#define FRUIT_HAS_MAX_ALIGN_T 1
-
-// Whether the compiler defines std::is_trivially_copyable.
-#define FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE 1
-
-// Whether the compiler defines __has_trivial_copy.
-// Ignored if FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE is set.
-#define FRUIT_HAS_HAS_TRIVIAL_COPY 1
-
-// Whether the compiler defines __is_trivially_copyable.
-// Ignored if FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE is set.
-#define FRUIT_HAS_IS_TRIVIALLY_COPYABLE 1
-
-// Whether the compiler defines std::is_trivially_copy_constructible.
-#define FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE 1
-
-// Whether typeid() is available. Typically, it is unless RTTI is disabled.
-#define FRUIT_HAS_TYPEID 1
-
-// Whether typeid() is constexpr. Typically, it is except in MSVC.
-#define FRUIT_HAS_CONSTEXPR_TYPEID 1
-
-// Whether abi::__cxa_demangle() is available after including cxxabi.h.
-#define FRUIT_HAS_CXA_DEMANGLE 1
-
-#define FRUIT_USES_BOOST 1
-
-#define FRUIT_HAS_ALWAYS_INLINE_ATTRIBUTE 1
-
-#define FRUIT_HAS_FORCEINLINE 0
-
-#define FRUIT_HAS_ATTRIBUTE_DEPRECATED 0
-
-#define FRUIT_HAS_GCC_ATTRIBUTE_DEPRECATED 1
-
-#define FRUIT_HAS_DECLSPEC_DEPRECATED 0
-
-#define FRUIT_HAS_MSVC_ASSUME 0
-
-#define FRUIT_HAS_BUILTIN_UNREACHABLE 1
-
-#endif // FRUIT_CONFIG_BASE_H
diff --git a/configuration/bazel/gcc_attribute_deprecated.cpp b/configuration/bazel/gcc_attribute_deprecated.cpp
new file mode 100644
index 0000000..6d0bf5f
--- /dev/null
+++ b/configuration/bazel/gcc_attribute_deprecated.cpp
@@ -0,0 +1,5 @@
+void f() __attribute__((deprecated));
+
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/has_trivial_copy.cpp b/configuration/bazel/has_trivial_copy.cpp
new file mode 100644
index 0000000..b9da7d1
--- /dev/null
+++ b/configuration/bazel/has_trivial_copy.cpp
@@ -0,0 +1,5 @@
+int main() {
+ bool b = __has_trivial_copy(int);
+ (void) b;
+ return 0;
+}
diff --git a/configuration/bazel/is_trivially_copyable.cpp b/configuration/bazel/is_trivially_copyable.cpp
new file mode 100644
index 0000000..b8b7379
--- /dev/null
+++ b/configuration/bazel/is_trivially_copyable.cpp
@@ -0,0 +1,5 @@
+int main() {
+ bool b = __is_trivially_copyable(int);
+ (void) b;
+ return 0;
+}
diff --git a/configuration/bazel/max_align_t.cpp b/configuration/bazel/max_align_t.cpp
new file mode 100644
index 0000000..37342f1
--- /dev/null
+++ b/configuration/bazel/max_align_t.cpp
@@ -0,0 +1,5 @@
+#include <cstddef>
+using X = max_align_t;
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/msvc_assume.cpp b/configuration/bazel/msvc_assume.cpp
new file mode 100644
index 0000000..cd9f6ed
--- /dev/null
+++ b/configuration/bazel/msvc_assume.cpp
@@ -0,0 +1,13 @@
+int f() {
+ static int x = 1;
+ if (x == 1) {
+ return 0;
+ } else {
+ __assume(0);
+ // Note: the lack of return here is intentional
+ }
+}
+
+int main() {
+ return f();
+}
diff --git a/configuration/bazel/std_is_trivially_copy_constructible.cpp b/configuration/bazel/std_is_trivially_copy_constructible.cpp
new file mode 100644
index 0000000..7cb8d5b
--- /dev/null
+++ b/configuration/bazel/std_is_trivially_copy_constructible.cpp
@@ -0,0 +1,6 @@
+#include <type_traits>
+int main() {
+ bool b = std::is_trivially_copy_constructible<int>::value;
+ (void) b;
+ return 0;
+}
diff --git a/configuration/bazel/std_is_trivially_copyable.cpp b/configuration/bazel/std_is_trivially_copyable.cpp
new file mode 100644
index 0000000..871b793
--- /dev/null
+++ b/configuration/bazel/std_is_trivially_copyable.cpp
@@ -0,0 +1,6 @@
+#include <type_traits>
+int main() {
+ bool b = std::is_trivially_copyable<int>::value;
+ (void) b;
+ return 0;
+}
diff --git a/configuration/bazel/std_max_align_t.cpp b/configuration/bazel/std_max_align_t.cpp
new file mode 100644
index 0000000..acec695
--- /dev/null
+++ b/configuration/bazel/std_max_align_t.cpp
@@ -0,0 +1,5 @@
+#include <cstddef>
+using X = std::max_align_t;
+int main() {
+ return 0;
+}
diff --git a/configuration/bazel/typeid.cpp b/configuration/bazel/typeid.cpp
new file mode 100644
index 0000000..9621d03
--- /dev/null
+++ b/configuration/bazel/typeid.cpp
@@ -0,0 +1,5 @@
+#include <typeinfo>
+int main() {
+ (void) typeid(int);
+ return 0;
+}
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index a00f93c..200118d 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,4 +1,13 @@
+# This is a restricted set compared to Fruit's code, the bar for Fruit code is higher.
+if(${FRUIT_ENABLE_CLANG_TIDY})
+ set(CMAKE_CXX_CLANG_TIDY
+ clang-tidy;
+ -header-filter=fruit;
+ -checks=${FRUIT_CLANG_TIDY_CHECKS},-google-explicit-constructor,-google-build-using-namespace;
+ -warnings-as-errors=*;)
+endif()
+
add_subdirectory(simple_injection)
add_subdirectory(hello_world)
diff --git a/extras/bazel_root/WORKSPACE b/extras/bazel_root/WORKSPACE
index 8622415..d74dafe 100644
--- a/extras/bazel_root/WORKSPACE
+++ b/extras/bazel_root/WORKSPACE
@@ -6,3 +6,13 @@ git_repository(
# GTest HEAD as of August 2018.
commit = "9c96f500a39df6915f8f1ab53b60be9889f1572b",
)
+
+git_repository(
+ name = "com_github_nelhage_rules_boost",
+ commit = "1e3a69bf2d5cd10c34b74f066054cd335d033d71",
+ remote = "https://github.com/nelhage/rules_boost",
+ shallow_since = "1591047380 -0700",
+)
+
+load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
+boost_deps()
diff --git a/extras/bazel_root/third_party/fruit/build b/extras/bazel_root/third_party/fruit/build
deleted file mode 120000
index 388dc92..0000000
--- a/extras/bazel_root/third_party/fruit/build
+++ /dev/null
@@ -1 +0,0 @@
-../../../../BUILD \ No newline at end of file
diff --git a/extras/bazel_usage_example/BUILD b/extras/bazel_usage_example/BUILD
new file mode 100644
index 0000000..47934aa
--- /dev/null
+++ b/extras/bazel_usage_example/BUILD
@@ -0,0 +1,8 @@
+
+licenses(["notice"])
+
+cc_binary(
+ name = "hello_world",
+ srcs = ["main.cpp"],
+ deps = ["@com_google_fruit//third_party/fruit"],
+)
diff --git a/extras/bazel_usage_example/WORKSPACE b/extras/bazel_usage_example/WORKSPACE
new file mode 100644
index 0000000..e037168
--- /dev/null
+++ b/extras/bazel_usage_example/WORKSPACE
@@ -0,0 +1,19 @@
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+ name = "com_github_nelhage_rules_boost",
+ branch = "master",
+ remote = "https://github.com/nelhage/rules_boost",
+)
+
+load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
+boost_deps()
+
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+ name = "com_google_fruit",
+ remote = "https://github.com/google/fruit",
+ branch = "master",
+ strip_prefix = "extras/bazel_root",
+)
diff --git a/extras/bazel_usage_example/main.cpp b/extras/bazel_usage_example/main.cpp
new file mode 100644
index 0000000..4364993
--- /dev/null
+++ b/extras/bazel_usage_example/main.cpp
@@ -0,0 +1,55 @@
+
+#include <fruit/fruit.h>
+#include <iostream>
+
+using fruit::Component;
+using fruit::Injector;
+
+class Writer {
+public:
+ virtual void write(std::string s) = 0;
+};
+
+class StdoutWriter : public Writer {
+public:
+ // Like "StdoutWriter() = default;" but also marks this constructor as the
+ // one to use for injection.
+ INJECT(StdoutWriter()) = default;
+
+ virtual void write(std::string s) override {
+ std::cout << s;
+ }
+};
+
+class Greeter {
+public:
+ virtual void greet() = 0;
+};
+
+class GreeterImpl : public Greeter {
+private:
+ Writer* writer;
+
+public:
+ // Like "GreeterImpl(Writer* writer) {...}" but also marks this constructor
+ // as the one to use for injection.
+ INJECT(GreeterImpl(Writer* writer)) : writer(writer) {}
+
+ virtual void greet() override {
+ writer->write("Hello world!\n");
+ }
+};
+
+Component<Greeter> getGreeterComponent() {
+ return fruit::createComponent().bind<Writer, StdoutWriter>().bind<Greeter, GreeterImpl>();
+}
+
+int main() {
+
+ Injector<Greeter> injector(getGreeterComponent);
+ Greeter* greeter = injector.get<Greeter*>();
+
+ greeter->greet();
+
+ return 0;
+}
diff --git a/extras/benchmark/boost_di_source_generator.py b/extras/benchmark/boost_di_source_generator.py
index 6a3f91f..d2858a1 100644
--- a/extras/benchmark/boost_di_source_generator.py
+++ b/extras/benchmark/boost_di_source_generator.py
@@ -11,23 +11,27 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import List
-def generate_files(injection_graph, generate_runtime_bench_code):
+import networkx as nx
+
+
+def generate_files(injection_graph: nx.DiGraph, generate_runtime_bench_code: bool):
file_content_by_name = dict()
- for node_id in injection_graph.nodes_iter():
- deps = injection_graph.successors(node_id)
+ for node_id in injection_graph.nodes:
+ deps = list(injection_graph.successors(node_id))
file_content_by_name['component%s.h' % node_id] = _generate_component_header(node_id, deps)
file_content_by_name['component%s.cpp' % node_id] = _generate_component_source(node_id, deps)
[toplevel_node] = [node_id
- for node_id in injection_graph.nodes_iter()
- if not injection_graph.predecessors(node_id)]
+ for node_id in injection_graph.nodes
+ if not any(True for p in injection_graph.predecessors(node_id))]
file_content_by_name['main.cpp'] = _generate_main(injection_graph, toplevel_node, generate_runtime_bench_code)
return file_content_by_name
-def _generate_component_header(component_index, deps):
+def _generate_component_header(component_index: int, deps: List[int]):
fields = ''.join(['std::shared_ptr<Interface%s> x%s;\n' % (dep, dep)
for dep in deps])
component_deps = ''.join([', std::shared_ptr<Interface%s>' % dep for dep in deps])
@@ -39,7 +43,7 @@ def _generate_component_header(component_index, deps):
#define COMPONENT{component_index}_H
#include <boost/di.hpp>
-#include <boost/di/extension/scopes/scoped_scope.hpp>
+#include <boost/di/extension/scopes/scoped.hpp>
#include <memory>
// Example include that the code might use
@@ -69,7 +73,7 @@ auto x{component_index}Component = [] {{
"""
return template.format(**locals())
-def _generate_component_source(component_index, deps):
+def _generate_component_source(component_index: int, deps: List[int]):
param_initializers = ', '.join('x%s(x%s)' % (dep, dep)
for dep in deps)
if param_initializers:
@@ -86,12 +90,12 @@ X{component_index}::X{component_index}({component_deps})
"""
return template.format(**locals())
-def _generate_main(injection_graph, toplevel_component, generate_runtime_bench_code):
+def _generate_main(injection_graph: nx.DiGraph, toplevel_component: int, generate_runtime_bench_code: bool):
include_directives = ''.join('#include "component%s.h"\n' % index
- for index in injection_graph.nodes_iter())
+ for index in injection_graph.nodes)
injector_params = ', '.join('x%sComponent()' % index
- for index in injection_graph.nodes_iter())
+ for index in injection_graph.nodes)
if generate_runtime_bench_code:
template = """
diff --git a/extras/benchmark/format_bench_results.py b/extras/benchmark/format_bench_results.py
index 49c4893..614db07 100755
--- a/extras/benchmark/format_bench_results.py
+++ b/extras/benchmark/format_bench_results.py
@@ -15,30 +15,47 @@
import argparse
import json
+from typing import Tuple, List, Dict, Union, Callable, Any, Sequence, Set, Iterable
+
import yaml
from collections import defaultdict
-def extract_results(bench_results, fixed_benchmark_params, column_dimension, row_dimension, result_dimension):
- table_data = defaultdict(lambda: dict())
+def extract_results(bench_results: List[Dict[str, Dict[Any, Any]]],
+ fixed_benchmark_params: Dict[str, Union[str, Tuple[str, ...]]],
+ column_dimension: str,
+ row_dimension: str,
+ result_dimension: str) -> Tuple[Dict[str, Dict[str, Dict[str, Any]]],
+ Set[Tuple[List[Tuple[str, str]], ...]],
+ Set[Tuple[Tuple[List[Tuple[str, str]], ...],
+ str]]]:
+ table_data = defaultdict(lambda: dict()) # type: Dict[str, Dict[str, Dict[str, Any]]]
remaining_dimensions_by_row_column = dict()
+ used_bench_results = set() # type: Set[Tuple[List[Tuple[str, str]], ...]]
+ used_bench_result_values = set() # type: Set[Tuple[Tuple[List[Tuple[str, str]], ...], str]]
for bench_result in bench_results:
try:
params = {dimension_name: make_immutable(dimension_value)
for dimension_name, dimension_value in bench_result['benchmark'].items()}
+ original_params = dict(params)
results = bench_result['results']
+ matches = True
+ if result_dimension not in results:
+ # result_dimension not found in this result, skip
+ matches = False
for param_name, param_value in fixed_benchmark_params.items():
- if params.get(param_name) != param_value:
+ if (isinstance(param_value, tuple) and params.get(param_name) in param_value) or (params.get(param_name) == param_value):
+ pass
+ else:
# fixed_benchmark_params not satisfied by this result, skip
- break
- if result_dimension not in results:
- # result_dimension not found in this result, skip
- break
- params.pop(param_name)
- else:
+ matches = False
+ if matches:
# fixed_benchmark_params were satisfied by these params (and were removed)
assert row_dimension in params.keys(), '%s not in %s' % (row_dimension, params.keys())
assert column_dimension in params.keys(), '%s not in %s' % (column_dimension, params.keys())
assert result_dimension in results, '%s not in %s' % (result_dimension, results)
+ used_bench_results.add(tuple(sorted(original_params.items())))
+ used_bench_result_values.add((tuple(sorted(original_params.items())),
+ result_dimension))
row_value = params[row_dimension]
column_value = params[column_dimension]
remaining_dimensions = params.copy()
@@ -48,21 +65,16 @@ def extract_results(bench_results, fixed_benchmark_params, column_dimension, row
previous_remaining_dimensions = remaining_dimensions_by_row_column[(row_value, column_value)]
raise Exception(
'Found multiple benchmark results with the same fixed benchmark params, benchmark param for row and benchmark param for column, so a result can\'t be uniquely determined. '
- + 'Consider adding additional values in fixed_benchmark_params. Remaining dimensions: %s vs %s' % (
+ + 'Consider adding additional values in fixed_benchmark_params. Remaining dimensions:\n%s\nvs\n%s' % (
remaining_dimensions, previous_remaining_dimensions))
table_data[row_value][column_value] = results[result_dimension]
remaining_dimensions_by_row_column[(row_value, column_value)] = remaining_dimensions
except Exception as e:
raise Exception('While processing %s' % bench_result) from e
- return table_data
-
-
-def identity(x):
- return x
-
+ return table_data, used_bench_results, used_bench_result_values
# Takes a 2-dimensional array (list of lists) and prints a markdown table with that content.
-def print_markdown_table(table_data):
+def print_markdown_table(table_data: List[List[str]]) -> None:
max_content_length_by_column = [max([len(str(row[column_index])) for row in table_data])
for column_index in range(len(table_data[0]))]
for row_index in range(len(table_data)):
@@ -81,7 +93,11 @@ def print_markdown_table(table_data):
for column_index in range(len(row))])
+ '-|')
-def compute_min_max(table_data, row_headers, column_headers):
+# A sequence of length 2, with the lower and upper bound of the interval.
+# TODO: use a class instead.
+Interval = Sequence[float]
+
+def compute_min_max(table_data, row_headers: List[str], column_headers: List[str]) -> Interval:
values_by_row = {row_header: [table_data[row_header][column_header]
for column_header in column_headers
if column_header in table_data[row_header]]
@@ -93,8 +109,7 @@ def compute_min_max(table_data, row_headers, column_headers):
for row_header in row_headers])
return (min_in_table, max_in_table)
-
-def pretty_print_percentage_difference(baseline_value, current_value):
+def pretty_print_percentage_difference(baseline_value: Interval, current_value: Interval):
baseline_min = baseline_value[0]
baseline_max = baseline_value[1]
current_min = current_value[0]
@@ -108,6 +123,10 @@ def pretty_print_percentage_difference(baseline_value, current_value):
else:
return "%s - %s" % (percentage_min_s, percentage_max_s)
+DimensionPrettyPrinter = Callable[[Any], str]
+
+IntervalPrettyPrinter = Callable[[Interval, float, float], str]
+
# Takes a table as a dict of dicts (where each table_data[row_key][column_key] is a confidence interval) and prints it as a markdown table using
# the specified pretty print functions for column keys, row keys and values respectively.
@@ -117,18 +136,19 @@ def pretty_print_percentage_difference(baseline_value, current_value):
def print_confidence_intervals_table(table_name,
table_data,
baseline_table_data,
- column_header_pretty_printer=identity,
- row_header_pretty_printer=identity,
- value_pretty_printer=identity):
+ column_header_pretty_printer: DimensionPrettyPrinter,
+ row_header_pretty_printer: DimensionPrettyPrinter,
+ value_pretty_printer: IntervalPrettyPrinter,
+ row_sort_key: Callable[[Any], Any]):
if table_data == {}:
print('%s: (no data)' % table_name)
return
- row_headers = sorted(list(table_data.keys()))
+ row_headers = sorted(list(table_data.keys()), key=row_sort_key)
# We need to compute the union of the headers of all rows; some rows might be missing values for certain columns.
column_headers = sorted(set().union(*[list(row_values.keys()) for row_values in table_data.values()]))
if baseline_table_data:
- baseline_row_headers = sorted(list(baseline_table_data.keys()))
+ baseline_row_headers = sorted(list(baseline_table_data.keys()), key=row_sort_key)
baseline_column_headers = sorted(set().union(*[list(row_values.keys()) for row_values in baseline_table_data.values()]))
unmached_baseline_column_headers = set(baseline_row_headers) - set(row_headers)
if unmached_baseline_column_headers:
@@ -166,15 +186,20 @@ def print_confidence_intervals_table(table_name,
print_markdown_table(table_content)
-def format_string_pretty_printer(format_string):
- def pretty_print(s):
+def format_string_pretty_printer(format_string: str) -> Callable[[str], str]:
+ def pretty_print(s: str):
return format_string % s
return pretty_print
+def float_to_str(x: float) -> str:
+ if x > 100:
+ return str(int(x))
+ else:
+ return '%.2g' % x
-def interval_pretty_printer(interval, unit, multiplier):
- interval = interval.copy()
+def interval_pretty_printer(interval: Interval, unit: str, multiplier: float) -> str:
+ interval = list(interval) # type: List[Any]
interval[0] *= multiplier
interval[1] *= multiplier
@@ -184,11 +209,11 @@ def interval_pretty_printer(interval, unit, multiplier):
if int(interval[0]) == interval[0] and interval[0] >= 10:
interval[0] = int(interval[0])
else:
- interval[0] = '%.3g' % interval[0]
+ interval[0] = float_to_str(interval[0])
if int(interval[1]) == interval[1] and interval[1] >= 10:
interval[1] = int(interval[1])
else:
- interval[1] = '%.3g' % interval[1]
+ interval[1] = float_to_str(interval[1])
if interval[0] == interval[1]:
return '%s %s' % (interval[0], unit)
@@ -198,7 +223,7 @@ def interval_pretty_printer(interval, unit, multiplier):
# Finds the best unit to represent values in the range [min_value, max_value].
# The units must be specified as an ordered list [multiplier1, ..., multiplierN]
-def find_best_unit(units, min_value, max_value):
+def find_best_unit(units: List[float], min_value: float, max_value: float) -> float:
assert min_value <= max_value
if max_value <= units[0]:
return units[0]
@@ -222,7 +247,7 @@ def find_best_unit(units, min_value, max_value):
return units[0]
-def time_interval_pretty_printer(time_interval, min_in_table, max_in_table):
+def time_interval_pretty_printer(time_interval: Interval, min_in_table: float, max_in_table: float) -> str:
sec = 1
milli = 0.001
micro = milli * milli
@@ -235,7 +260,7 @@ def time_interval_pretty_printer(time_interval, min_in_table, max_in_table):
return interval_pretty_printer(time_interval, unit=unit_name, multiplier=1 / unit)
-def file_size_interval_pretty_printer(file_size_interval, min_in_table, max_in_table):
+def file_size_interval_pretty_printer(file_size_interval: Interval, min_in_table: float, max_in_table: float) -> str:
byte = 1
kb = 1024
mb = kb * kb
@@ -254,11 +279,11 @@ def make_immutable(x):
return x
-def dict_pretty_printer(dict_data):
+def dict_pretty_printer(dict_data: List[Dict[str, Union[str, Tuple[str]]]]) -> Callable[[Union[str, Tuple[str]]], str]:
if isinstance(dict_data, list):
dict_data = {make_immutable(mapping['from']): mapping['to'] for mapping in dict_data}
- def pretty_print(s):
+ def pretty_print(s: Union[str, Tuple[str]]) -> str:
if s in dict_data:
return dict_data[s]
else:
@@ -267,7 +292,8 @@ def dict_pretty_printer(dict_data):
return pretty_print
-def determine_column_pretty_printer(pretty_printer_definition):
+
+def determine_column_pretty_printer(pretty_printer_definition: Dict[str, Any]) -> DimensionPrettyPrinter:
if 'format_string' in pretty_printer_definition:
return format_string_pretty_printer(pretty_printer_definition['format_string'])
@@ -276,19 +302,23 @@ def determine_column_pretty_printer(pretty_printer_definition):
raise Exception("Unrecognized pretty printer description: %s" % pretty_printer_definition)
-
-def determine_row_pretty_printer(pretty_printer_definition):
+def determine_row_pretty_printer(pretty_printer_definition: Dict[str, Any]) -> DimensionPrettyPrinter:
return determine_column_pretty_printer(pretty_printer_definition)
+def determine_row_sort_key(pretty_printer_definition: Dict[str, Any]) -> Callable[[Any], Any]:
+ if 'fixed_map' in pretty_printer_definition:
+ indexes = {x: i for i, x in enumerate(pretty_printer_definition['fixed_map'].keys())}
+ return lambda s: indexes[s]
-def determine_value_pretty_printer(unit):
+ return lambda x: x
+
+def determine_value_pretty_printer(unit: str) -> IntervalPrettyPrinter:
if unit == "seconds":
return time_interval_pretty_printer
if unit == "bytes":
return file_size_interval_pretty_printer
raise Exception("Unrecognized unit: %s" % unit)
-
def main():
parser = argparse.ArgumentParser(description='Runs all the benchmarks whose results are on the Fruit website.')
parser.add_argument('--benchmark-results',
@@ -314,17 +344,23 @@ def main():
baseline_bench_results = None
with open(args.benchmark_tables_definition, 'r') as f:
- for table_definition in yaml.load(f)["tables"]:
+ used_bench_results = set()
+ # Set of (Benchmark definition, Benchmark result name) pairs
+ used_bench_result_values = set()
+ config = yaml.full_load(f)
+ for table_definition in config["tables"]:
try:
fixed_benchmark_params = {dimension_name: make_immutable(dimension_value) for dimension_name, dimension_value in table_definition['benchmark_filter'].items()}
- table_data = extract_results(
+ table_data, last_used_bench_results, last_used_bench_result_values = extract_results(
bench_results,
fixed_benchmark_params=fixed_benchmark_params,
column_dimension=table_definition['columns']['dimension'],
row_dimension=table_definition['rows']['dimension'],
result_dimension=table_definition['results']['dimension'])
+ used_bench_results = used_bench_results.union(last_used_bench_results)
+ used_bench_result_values = used_bench_result_values.union(last_used_bench_result_values)
if baseline_bench_results:
- baseline_table_data = extract_results(
+ baseline_table_data, _, _ = extract_results(
baseline_bench_results,
fixed_benchmark_params=fixed_benchmark_params,
column_dimension=table_definition['columns']['dimension'],
@@ -340,13 +376,29 @@ def main():
baseline_table_data,
column_header_pretty_printer=determine_column_pretty_printer(columns_pretty_printer_definition),
row_header_pretty_printer=determine_row_pretty_printer(rows_pretty_printer_definition),
- value_pretty_printer=determine_value_pretty_printer(results_unit))
+ value_pretty_printer=determine_value_pretty_printer(results_unit),
+ row_sort_key=determine_row_sort_key(rows_pretty_printer_definition))
print()
print()
except Exception as e:
- print('While processing table:\n' + table_definition)
+ print('While processing table:\n%s' % table_definition)
print()
raise e
+ allowed_unused_benchmarks = set(config.get('allowed_unused_benchmarks', []))
+ allowed_unused_benchmark_results = set(config.get('allowed_unused_benchmark_results', []))
+ for bench_result in bench_results:
+ params = {dimension_name: make_immutable(dimension_value)
+ for dimension_name, dimension_value in bench_result['benchmark'].items()}
+ benchmark_defn = tuple(sorted(params.items()))
+ if benchmark_defn not in used_bench_results:
+ if params['name'] not in allowed_unused_benchmarks:
+ print('Warning: benchmark result did not match any tables: %s' % params)
+ else:
+ unused_result_dimensions = {result_dimension
+ for result_dimension in bench_result['results'].keys()
+ if (benchmark_defn, result_dimension) not in used_bench_result_values and result_dimension not in allowed_unused_benchmark_results}
+ if unused_result_dimensions:
+ print('Warning: unused result dimensions %s in benchmark result %s' % (unused_result_dimensions, params))
if __name__ == "__main__":
diff --git a/extras/benchmark/fruit_source_generator.py b/extras/benchmark/fruit_source_generator.py
index 894bd28..f7bc786 100644
--- a/extras/benchmark/fruit_source_generator.py
+++ b/extras/benchmark/fruit_source_generator.py
@@ -11,29 +11,32 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import List
+import networkx as nx
-def generate_files(injection_graph, generate_runtime_bench_code, use_normalized_component=False):
+
+def generate_files(injection_graph: nx.DiGraph, generate_runtime_bench_code: bool, use_normalized_component: bool=False):
if use_normalized_component:
assert not generate_runtime_bench_code
file_content_by_name = dict()
- for node_id in injection_graph.nodes_iter():
+ for node_id in injection_graph.nodes:
file_content_by_name['component%s.h' % node_id] = _generate_component_header(node_id)
- file_content_by_name['component%s.cpp' % node_id] = _generate_component_source(node_id, injection_graph.successors(node_id))
+ file_content_by_name['component%s.cpp' % node_id] = _generate_component_source(node_id, list(injection_graph.successors(node_id)))
[toplevel_node] = [node_id
- for node_id in injection_graph.nodes_iter()
- if not injection_graph.predecessors(node_id)]
+ for node_id in injection_graph.nodes
+ if not any(True for p in injection_graph.predecessors(node_id))]
file_content_by_name['main.cpp'] = _generate_main(toplevel_node, generate_runtime_bench_code)
return file_content_by_name
-def _get_component_type(component_index):
+def _get_component_type(component_index: int):
return 'fruit::Component<Interface{component_index}>'.format(**locals())
-def _generate_component_header(component_index):
+def _generate_component_header(component_index: int):
component_type = _get_component_type(component_index)
template = """
#ifndef COMPONENT{component_index}_H
@@ -54,7 +57,7 @@ struct Interface{component_index} {{
"""
return template.format(**locals())
-def _generate_component_source(component_index, deps):
+def _generate_component_source(component_index: int, deps: List[int]):
include_directives = ''.join(['#include "component%s.h"\n' % index for index in deps + [component_index]])
fields = ''.join(['Interface%s& x%s;\n' % (dep, dep)
@@ -95,7 +98,7 @@ struct X{component_index} : public Interface{component_index} {{
return template.format(**locals())
-def _generate_main(toplevel_component, generate_runtime_bench_code):
+def _generate_main(toplevel_component: int, generate_runtime_bench_code: bool):
if generate_runtime_bench_code:
template = """
#include "component{toplevel_component}.h"
diff --git a/extras/benchmark/generate_benchmark.py b/extras/benchmark/generate_benchmark.py
index cee0017..411e9a6 100755
--- a/extras/benchmark/generate_benchmark.py
+++ b/extras/benchmark/generate_benchmark.py
@@ -24,9 +24,9 @@ import argparse
import networkx as nx
-def generate_injection_graph(num_components_with_no_deps,
- num_components_with_deps,
- num_deps):
+def generate_injection_graph(num_components_with_no_deps: int,
+ num_components_with_deps: int,
+ num_deps: int):
injection_graph = nx.DiGraph()
num_used_ids = 0
@@ -71,23 +71,23 @@ def generate_injection_graph(num_components_with_no_deps,
return injection_graph
def generate_benchmark(
- di_library,
- compiler,
- cxx_std,
- output_dir,
- num_components_with_no_deps,
- num_components_with_deps,
- num_deps,
- generate_runtime_bench_code,
- use_exceptions=True,
- use_rtti=True,
- fruit_build_dir=None,
- fruit_sources_dir=None,
- boost_di_sources_dir=None,
- generate_debuginfo=False,
- use_new_delete=False,
- use_interfaces=False,
- use_normalized_component=False):
+ di_library: str,
+ compiler: str,
+ cxx_std: str,
+ output_dir: str,
+ num_components_with_no_deps: int,
+ num_components_with_deps: int,
+ num_deps: int,
+ generate_runtime_bench_code: bool,
+ use_exceptions: bool=True,
+ use_rtti: bool=True,
+ fruit_build_dir: str=None,
+ fruit_sources_dir: str=None,
+ boost_di_sources_dir: str=None,
+ generate_debuginfo: bool=False,
+ use_new_delete: bool=False,
+ use_interfaces: bool=False,
+ use_normalized_component: bool=False):
"""Generates a sample codebase using the specified DI library, meant for benchmarking.
:param boost_di_sources_dir: this is only used if di_library=='boost_di', it can be None otherwise.
@@ -135,8 +135,8 @@ def generate_benchmark(
other_compile_flags.append('-fno-exceptions')
if not use_rtti:
other_compile_flags.append('-fno-rtti')
- compile_command = '%s -std=%s -MMD -MP -O2 -W -Wall -Werror -DNDEBUG -ftemplate-depth=10000 %s %s' % (compiler, cxx_std, include_flags, ' '.join(other_compile_flags))
- link_command = '%s -std=%s -O2 -W -Wall -Werror %s %s' % (compiler, cxx_std, rpath_flags, library_dirs_flags)
+ compile_command = '%s -std=%s -MMD -MP -O2 -W -Wall -DNDEBUG -ftemplate-depth=10000 %s %s' % (compiler, cxx_std, include_flags, ' '.join(other_compile_flags))
+ link_command = '%s -std=%s -O2 -W -Wall %s %s' % (compiler, cxx_std, rpath_flags, library_dirs_flags)
# GCC requires passing the -lfruit flag *after* all object files to be linked for some reason.
link_command_suffix = link_libraries_flags
diff --git a/extras/benchmark/makefile_generator.py b/extras/benchmark/makefile_generator.py
index 083fd36..7781a6e 100644
--- a/extras/benchmark/makefile_generator.py
+++ b/extras/benchmark/makefile_generator.py
@@ -11,23 +11,30 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import List
-def generate_makefile(cpp_files, executable_name, compile_command, link_command, link_command_suffix):
+def generate_makefile(cpp_files: List[str], executable_name: str, compile_command: str, link_command: str, link_command_suffix: str):
assert executable_name + '.cpp' in cpp_files, '%s.cpp in %s' % (executable_name, cpp_files)
link_rule_template = """
{executable_name}: {object_files}
\t{link_command} {object_files} -o {executable_name} {link_command_suffix}
+
+{executable_name}_ram.txt: {object_files_ram_txt}
+\t(cat {object_files_ram_txt}; /bin/time -v {link_command} {object_files} -o {executable_name}.tmp {link_command_suffix} 2>&1 | fgrep 'Maximum resident set size' | sed 's|.*: ||') >{executable_name}_ram.txt
"""
compile_rule_template = """
{name}.o: {name}.cpp
\t{compile_command} -c {name}.cpp -o {name}.o
+
+{name}.o_ram.txt: {name}.cpp
+\t/bin/time -v {compile_command} -c {name}.cpp -o {name}.o 2>&1 | fgrep 'Maximum resident set size' | sed 's|.*: ||' >{name}.o_ram.txt
"""
clean_rule_template = """
clean:
-\trm -f {object_files} {dep_files} {executable_name}
+\trm -f {object_files} {dep_files} {executable_name} {executable_name}_ram.txt {object_files_ram_txt}
"""
dep_file_deps = """
@@ -40,6 +47,7 @@ include {dep_files}
compile_rules = []
object_files = []
+ object_files_ram_txt = []
dep_files = []
for cpp_file in cpp_files:
assert cpp_file.endswith('.cpp')
@@ -50,16 +58,19 @@ include {dep_files}
compile_command=compile_command)
compile_rules.append(compile_rule)
object_files.append('%s.o' % source)
+ object_files_ram_txt.append('%s.o_ram.txt' % source)
dep_files.append('%s.d' % source)
link_rule = link_rule_template.format(
object_files=' '.join(object_files),
+ object_files_ram_txt=' '.join(object_files_ram_txt),
link_command=link_command,
link_command_suffix=link_command_suffix,
executable_name=executable_name)
clean_rule = clean_rule_template.format(
object_files=' '.join(object_files),
+ object_files_ram_txt=' '.join(object_files_ram_txt),
executable_name=executable_name,
dep_files=' '.join(dep_files))
diff --git a/extras/benchmark/new_delete_benchmark.cpp b/extras/benchmark/new_delete_benchmark.cpp
index 8131eac..d30d835 100644
--- a/extras/benchmark/new_delete_benchmark.cpp
+++ b/extras/benchmark/new_delete_benchmark.cpp
@@ -29,6 +29,9 @@
#elif MULTIPLIER == 100
#define REPEAT(X) REPEAT_100(X, _)
+#elif MULTIPLIER == 250
+#define REPEAT(X) REPEAT_250(X, _)
+
#elif MULTIPLIER == 1000
#define REPEAT(X) REPEAT_1000(X, _)
@@ -48,12 +51,21 @@
R PLACEHOLDER(X, I##5) R PLACEHOLDER(X, I##6) R PLACEHOLDER(X, I##7) R PLACEHOLDER(X, I##8) \
R PLACEHOLDER(X, I##9)
+#define META_REPEAT_5(R, X, I) \
+ R PLACEHOLDER(X, I##0) R PLACEHOLDER(X, I##1) R PLACEHOLDER(X, I##2) R PLACEHOLDER(X, I##3) R PLACEHOLDER(X, I##4)
+
#define REPEAT_1(X, I) X(I)
+#define REPEAT_5(X, I) META_REPEAT_5(REPEAT_1, X, I)
+
#define REPEAT_10(X, I) META_REPEAT_10(REPEAT_1, X, I)
+#define REPEAT_25(X, I) META_REPEAT_5(REPEAT_5, X, I)
+
#define REPEAT_100(X, I) META_REPEAT_10(REPEAT_10, X, I)
+#define REPEAT_250(X, I) META_REPEAT_10(REPEAT_25, X, I)
+
#define REPEAT_1000(X, I) META_REPEAT_10(REPEAT_100, X, I)
using namespace std;
diff --git a/extras/benchmark/no_di_library_source_generator.py b/extras/benchmark/no_di_library_source_generator.py
index 2d91d04..65046a2 100644
--- a/extras/benchmark/no_di_library_source_generator.py
+++ b/extras/benchmark/no_di_library_source_generator.py
@@ -12,13 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
+from typing import List
+
import networkx as nx
-def generate_files(injection_graph, use_new_delete, use_interfaces, generate_runtime_bench_code):
+def generate_files(injection_graph: nx.DiGraph, use_new_delete: bool, use_interfaces: bool, generate_runtime_bench_code: bool):
file_content_by_name = dict()
- for node_id in injection_graph.nodes_iter():
- deps = injection_graph.successors(node_id)
+ for node_id in injection_graph.nodes:
+ deps = list(injection_graph.successors(node_id))
if use_interfaces:
file_content_by_name['class%s_interface.h' % node_id] = _generate_class_interface_header(node_id)
file_content_by_name['class%s.h' % node_id] = _generate_class_header_with_interfaces(node_id, deps)
@@ -31,7 +33,7 @@ def generate_files(injection_graph, use_new_delete, use_interfaces, generate_run
return file_content_by_name
-def _generate_class_interface_header(class_index):
+def _generate_class_interface_header(class_index: int):
template = """
#ifndef CLASS{class_index}_INTERFACE_H
#define CLASS{class_index}_INTERFACE_H
@@ -48,7 +50,7 @@ struct Interface{class_index} {{
"""
return template.format(**locals())
-def _generate_class_header_with_interfaces(class_index, deps):
+def _generate_class_header_with_interfaces(class_index: int, deps: List[int]):
include_directives = ''.join('#include "class%s_interface.h"\n' % index
for index in itertools.chain(deps, (class_index,)))
fields = ''.join('Interface%s& x%s;\n' % (index, index)
@@ -75,7 +77,7 @@ struct Class{class_index} : public Interface{class_index} {{
"""
return template.format(**locals())
-def _generate_class_header_without_interfaces(class_index, deps):
+def _generate_class_header_without_interfaces(class_index: int, deps: List[int]):
include_directives = ''.join('#include "class%s.h"\n' % index
for index in deps)
fields = ''.join('Class%s& x%s;\n' % (index, index)
@@ -101,7 +103,7 @@ struct Class{class_index} {{
"""
return template.format(**locals())
-def _generate_class_cpp_file_with_interfaces(class_index, deps):
+def _generate_class_cpp_file_with_interfaces(class_index: int, deps: List[int]):
constructor_params = ', '.join('Interface%s& x%s' % (index, index)
for index in deps)
field_initializers = ', '.join('x%s(x%s)' % (index, index)
@@ -127,7 +129,7 @@ Class{class_index}::~Class{class_index}() {{
"""
return template.format(**locals())
-def _generate_class_cpp_file_without_interfaces(class_index, deps):
+def _generate_class_cpp_file_without_interfaces(class_index: int, deps: List[int]):
constructor_params = ', '.join('Class%s& x%s' % (index, index)
for index in deps)
field_initializers = ', '.join('x%s(x%s)' % (index, index)
@@ -145,14 +147,14 @@ Class{class_index}::Class{class_index}({constructor_params})
return template.format(**locals())
-def _generate_main(injection_graph, use_interfaces, use_new_delete, generate_runtime_bench_code):
+def _generate_main(injection_graph: nx.DiGraph, use_interfaces: bool, use_new_delete: bool, generate_runtime_bench_code: bool):
[toplevel_class_index] = [node_id
- for node_id in injection_graph.nodes_iter()
- if not injection_graph.predecessors(node_id)]
+ for node_id in injection_graph.nodes
+ if not any(True for p in injection_graph.predecessors(node_id))]
if use_interfaces:
include_directives = ''.join('#include "class%s.h"\n' % index
- for index in injection_graph.nodes_iter())
+ for index in injection_graph.nodes)
else:
include_directives = '#include "class%s.h"\n' % toplevel_class_index
@@ -171,7 +173,7 @@ def _generate_main(injection_graph, use_interfaces, use_new_delete, generate_run
for class_index in reversed(list(nx.topological_sort(injection_graph))))
void_casts = ''.join('(void) x%s;\n' % index
- for index in injection_graph.nodes_iter())
+ for index in injection_graph.nodes)
if generate_runtime_bench_code:
template = """
diff --git a/extras/benchmark/run_benchmarks.py b/extras/benchmark/run_benchmarks.py
index d19232b..1fc3fd4 100755
--- a/extras/benchmark/run_benchmarks.py
+++ b/extras/benchmark/run_benchmarks.py
@@ -22,13 +22,15 @@ import tempfile
import os
import shutil
import itertools
+import traceback
+from typing import Dict, List, Tuple, Optional, Any, TypeVar, Callable, Iterable
+
import numpy
import subprocess
import yaml
from numpy import floor, log10
import scipy
import multiprocessing
-import sh
import json
import statsmodels.stats.api as stats
from generate_benchmark import generate_benchmark
@@ -36,7 +38,7 @@ import git
from functools import lru_cache as memoize
class CommandFailedException(Exception):
- def __init__(self, command, stdout, stderr, error_code):
+ def __init__(self, command: List[str], stdout: str, stderr: str, error_code: str):
self.command = command
self.stdout = stdout
self.stderr = stderr
@@ -53,7 +55,7 @@ class CommandFailedException(Exception):
{stderr}
''').format(command=self.command, error_code=self.error_code, stdout=self.stdout, stderr=self.stderr)
-def run_command(executable, args=[], cwd=None, env=None):
+def run_command(executable: str, args: List[Any]=[], cwd: str=None, env: Dict[str, str]=None) -> Tuple[str, str]:
args = [str(arg) for arg in args]
command = [executable] + args
try:
@@ -70,7 +72,7 @@ compile_flags = ['-O2', '-DNDEBUG']
make_args = ['-j', multiprocessing.cpu_count() + 1]
-def parse_results(result_lines):
+def parse_results(result_lines: List[str]) -> Dict[str, float]:
"""
Parses results from the format:
['Dimension name1 = 123',
@@ -89,7 +91,7 @@ def parse_results(result_lines):
# We memoize the result since this might be called repeatedly and it's somewhat expensive.
@memoize(maxsize=None)
-def determine_compiler_name(compiler_executable_name):
+def determine_compiler_name(compiler_executable_name: str) -> str:
tmpdir = tempfile.gettempdir() + '/fruit-determine-compiler-version-dir'
ensure_empty_dir(tmpdir)
with open(tmpdir + '/CMakeLists.txt', 'w') as file:
@@ -112,7 +114,7 @@ def determine_compiler_name(compiler_executable_name):
# Returns a pair (sha256_hash, version_name), where version_name will be None if no version tag was found at HEAD.
@memoize(maxsize=None)
-def git_repo_info(repo_path):
+def git_repo_info(repo_path: str) -> Tuple[str, str]:
repo = git.Repo(repo_path)
head_tags = [tag.name for tag in repo.tags if tag.commit == repo.head.commit and re.match('v[0-9].*', tag.name)]
if head_tags == []:
@@ -129,7 +131,7 @@ def git_repo_info(repo_path):
# We put the compiler name/version in the results because the same 'compiler' value might refer to different compiler versions
# (e.g. if GCC 6.0.0 is installed when benchmarks are run, then it's updated to GCC 6.0.1 and finally the results are formatted, we
# want the formatted results to say "GCC 6.0.0" instead of "GCC 6.0.1").
-def add_synthetic_benchmark_parameters(original_benchmark_parameters, path_to_code_under_test):
+def add_synthetic_benchmark_parameters(original_benchmark_parameters: Dict[str, Any], path_to_code_under_test: Optional[str]):
benchmark_params = original_benchmark_parameters.copy()
benchmark_params['compiler_name'] = determine_compiler_name(original_benchmark_parameters['compiler'])
if path_to_code_under_test is not None:
@@ -140,8 +142,13 @@ def add_synthetic_benchmark_parameters(original_benchmark_parameters, path_to_co
return benchmark_params
-class SimpleNewDeleteRunTimeBenchmark:
- def __init__(self, benchmark_definition, fruit_benchmark_sources_dir):
+class Benchmark:
+ def prepare(self) -> None: ...
+ def run(self) -> Dict[str, float]: ...
+ def describe(self) -> str: ...
+
+class SimpleNewDeleteRunTimeBenchmark(Benchmark):
+ def __init__(self, benchmark_definition: Dict[str, Any], fruit_benchmark_sources_dir: str):
self.benchmark_definition = add_synthetic_benchmark_parameters(benchmark_definition, path_to_code_under_test=None)
self.fruit_benchmark_sources_dir = fruit_benchmark_sources_dir
@@ -170,8 +177,8 @@ class SimpleNewDeleteRunTimeBenchmark:
return self.benchmark_definition
-class FruitSingleFileCompileTimeBenchmark:
- def __init__(self, benchmark_definition, fruit_sources_dir, fruit_build_dir, fruit_benchmark_sources_dir):
+class FruitSingleFileCompileTimeBenchmark(Benchmark):
+ def __init__(self, benchmark_definition: Dict[str, Any], fruit_sources_dir: str, fruit_build_dir: str, fruit_benchmark_sources_dir: str):
self.benchmark_definition = add_synthetic_benchmark_parameters(benchmark_definition, path_to_code_under_test=fruit_sources_dir)
self.fruit_sources_dir = fruit_sources_dir
self.fruit_build_dir = fruit_build_dir
@@ -207,7 +214,7 @@ class FruitSingleFileCompileTimeBenchmark:
return self.benchmark_definition
-def ensure_empty_dir(dirname):
+def ensure_empty_dir(dirname: str):
# We start by creating the directory instead of just calling rmtree with ignore_errors=True because that would ignore
# all errors, so we might otherwise go ahead even if the directory wasn't properly deleted.
os.makedirs(dirname, exist_ok=True)
@@ -215,7 +222,7 @@ def ensure_empty_dir(dirname):
os.makedirs(dirname)
-class GenericGeneratedSourcesBenchmark:
+class GenericGeneratedSourcesBenchmark(Benchmark):
def __init__(self,
di_library,
benchmark_definition,
@@ -258,6 +265,10 @@ class GenericGeneratedSourcesBenchmark:
self.arbitrary_files = [files[i * (len(files) // (num_files_changed + 2))]
for i in range(1, num_files_changed + 1)]
+ def prepare_compile_memory_benchmark(self):
+ self.prepare_compile_benchmark()
+ self.run_compile_memory_benchmark()
+
def prepare_runtime_benchmark(self):
self.prepare_compile_benchmark()
self.run_make_build()
@@ -289,6 +300,16 @@ class GenericGeneratedSourcesBenchmark:
result = {'incremental_compile_time': end - start}
return result
+ def run_compile_memory_benchmark(self):
+ run_command('make', args=make_args + ['clean'], cwd=self.tmpdir)
+ run_command('make', args=make_args + ['main_ram.txt'], cwd=self.tmpdir)
+ with open(self.tmpdir + '/main_ram.txt') as f:
+ ram_usages = [int(n)*1024 for n in f.readlines()]
+ return {
+ 'total_max_ram_usage': sum(ram_usages),
+ 'max_ram_usage': max(ram_usages),
+ }
+
def run_runtime_benchmark(self):
num_classes = self.benchmark_definition['num_classes']
loop_factor = self.benchmark_definition['loop_factor']
@@ -340,6 +361,17 @@ class IncrementalCompileTimeBenchmark(GenericGeneratedSourcesBenchmark):
def run(self):
return self.run_incremental_compile_benchmark()
+class CompileMemoryBenchmark(GenericGeneratedSourcesBenchmark):
+ def __init__(self, **kwargs):
+ super().__init__(generate_runtime_bench_code=False,
+ **kwargs)
+
+ def prepare(self):
+ self.prepare_compile_memory_benchmark()
+
+ def run(self):
+ return self.run_compile_memory_benchmark()
+
class StartupTimeBenchmark(GenericGeneratedSourcesBenchmark):
def __init__(self, **kwargs):
super().__init__(generate_runtime_bench_code=False,
@@ -395,6 +427,13 @@ class FruitIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark):
fruit_sources_dir=fruit_sources_dir,
**kwargs)
+class FruitCompileMemoryBenchmark(CompileMemoryBenchmark):
+ def __init__(self, fruit_sources_dir, **kwargs):
+ super().__init__(di_library='fruit',
+ path_to_code_under_test=fruit_sources_dir,
+ fruit_sources_dir=fruit_sources_dir,
+ **kwargs)
+
class FruitRunTimeBenchmark(RunTimeBenchmark):
def __init__(self, fruit_sources_dir, **kwargs):
super().__init__(di_library='fruit',
@@ -444,6 +483,13 @@ class BoostDiIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark):
boost_di_sources_dir=boost_di_sources_dir,
**kwargs)
+class BoostDiCompileMemoryBenchmark(CompileMemoryBenchmark):
+ def __init__(self, boost_di_sources_dir, **kwargs):
+ super().__init__(di_library='boost_di',
+ path_to_code_under_test=boost_di_sources_dir,
+ boost_di_sources_dir=boost_di_sources_dir,
+ **kwargs)
+
class BoostDiRunTimeBenchmark(RunTimeBenchmark):
def __init__(self, boost_di_sources_dir, **kwargs):
super().__init__(di_library='boost_di',
@@ -484,6 +530,11 @@ class SimpleDiIncrementalCompileTimeBenchmark(IncrementalCompileTimeBenchmark):
super().__init__(di_library='none',
**kwargs)
+class SimpleDiCompileMemoryBenchmark(CompileMemoryBenchmark):
+ def __init__(self, **kwargs):
+ super().__init__(di_library='none',
+ **kwargs)
+
class SimpleDiRunTimeBenchmark(RunTimeBenchmark):
def __init__(self, **kwargs):
super().__init__(di_library='none',
@@ -514,6 +565,10 @@ class SimpleDiWithInterfacesIncrementalCompileTimeBenchmark(SimpleDiIncrementalC
def __init__(self, **kwargs):
super().__init__(use_interfaces=True, **kwargs)
+class SimpleDiWithInterfacesCompileMemoryBenchmark(SimpleDiCompileMemoryBenchmark):
+ def __init__(self, **kwargs):
+ super().__init__(use_interfaces=True, **kwargs)
+
class SimpleDiWithInterfacesRunTimeBenchmark(SimpleDiRunTimeBenchmark):
def __init__(self, **kwargs):
super().__init__(use_interfaces=True, **kwargs)
@@ -540,6 +595,10 @@ class SimpleDiWithInterfacesAndNewDeleteIncrementalCompileTimeBenchmark(SimpleDi
def __init__(self, **kwargs):
super().__init__(use_new_delete=True, **kwargs)
+class SimpleDiWithInterfacesAndNewDeleteCompileMemoryBenchmark(SimpleDiWithInterfacesCompileMemoryBenchmark):
+ def __init__(self, **kwargs):
+ super().__init__(use_new_delete=True, **kwargs)
+
class SimpleDiWithInterfacesAndNewDeleteRunTimeBenchmark(SimpleDiWithInterfacesRunTimeBenchmark):
def __init__(self, **kwargs):
super().__init__(use_new_delete=True, **kwargs)
@@ -559,13 +618,13 @@ class SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmarkWithoutExceptions
super().__init__(use_new_delete=True, **kwargs)
-def round_to_significant_digits(n, num_significant_digits):
+def round_to_significant_digits(n: float, num_significant_digits: int) -> float:
if n <= 0:
# We special-case this, otherwise the log10 below will fail.
return 0
return round(n, num_significant_digits - int(floor(log10(n))) - 1)
-def run_benchmark(benchmark, max_runs, timeout_hours, output_file, min_runs=3):
+def run_benchmark(benchmark: Benchmark, max_runs: int, timeout_hours: int, output_file: str, min_runs: int=3) -> None:
def run_benchmark_once():
print('Running benchmark... ', end='', flush=True)
result = benchmark.run()
@@ -627,7 +686,7 @@ def run_benchmark(benchmark, max_runs, timeout_hours, output_file, min_runs=3):
print()
-def expand_benchmark_definition(benchmark_definition):
+def expand_benchmark_definition(benchmark_definition: Dict[str, Any]) -> List[Dict[str, Tuple[Any]]]:
"""
Takes a benchmark definition, e.g.:
[{name: 'foo', compiler: ['g++-5', 'g++-6']},
@@ -650,12 +709,15 @@ def expand_benchmark_definition(benchmark_definition):
for value_combination in value_combinations]
-def expand_benchmark_definitions(benchmark_definitions):
+def expand_benchmark_definitions(benchmark_definitions: List[Dict[str, Any]]):
return list(itertools.chain(*[expand_benchmark_definition(benchmark_definition) for benchmark_definition in benchmark_definitions]))
-def group_by(l, element_to_key):
- """Takes a list and returns a dict of sublists, where the elements are grouped using the provided function"""
- result = defaultdict(list)
+T = TypeVar('T')
+K = TypeVar('K')
+
+def group_by(l: List[T], element_to_key: Callable[[T], K]) -> Iterable[Tuple[K, List[T]]]:
+ """Takes a list and returns a list of sublists, where the elements are grouped using the provided function"""
+ result = defaultdict(list) # type: Dict[K, List[T]]
for elem in l:
result[element_to_key(elem)].append(elem)
return result.items()
@@ -690,7 +752,7 @@ def main():
fruit_build_dir = tempfile.gettempdir() + '/fruit-benchmark-build-dir'
with open(args.benchmark_definition, 'r') as f:
- yaml_file_content = yaml.load(f)
+ yaml_file_content = yaml.full_load(f)
global_definitions = yaml_file_content['global']
benchmark_definitions = expand_benchmark_definitions(yaml_file_content['benchmarks'])
@@ -702,24 +764,28 @@ def main():
(benchmark_definition['compiler'], tuple(benchmark_definition['additional_cmake_args']))):
print('Preparing for benchmarks with the compiler %s, with additional CMake args %s' % (compiler_executable_name, additional_cmake_args))
- # We compute this here (and memoize the result) so that the benchmark's describe() will retrieve the cached
- # value instantly.
- determine_compiler_name(compiler_executable_name)
-
- # Build Fruit in fruit_build_dir, so that fruit_build_dir points to a built Fruit (useful for e.g. the config header).
- shutil.rmtree(fruit_build_dir, ignore_errors=True)
- os.makedirs(fruit_build_dir)
- modified_env = os.environ.copy()
- modified_env['CXX'] = compiler_executable_name
- run_command('cmake',
- args=[
- args.fruit_sources_dir,
- '-DCMAKE_BUILD_TYPE=Release',
- *additional_cmake_args,
- ],
- cwd=fruit_build_dir,
- env=modified_env)
- run_command('make', args=make_args, cwd=fruit_build_dir)
+ try:
+ # We compute this here (and memoize the result) so that the benchmark's describe() will retrieve the cached
+ # value instantly.
+ determine_compiler_name(compiler_executable_name)
+
+ # Build Fruit in fruit_build_dir, so that fruit_build_dir points to a built Fruit (useful for e.g. the config header).
+ shutil.rmtree(fruit_build_dir, ignore_errors=True)
+ os.makedirs(fruit_build_dir)
+ modified_env = os.environ.copy()
+ modified_env['CXX'] = compiler_executable_name
+ run_command('cmake',
+ args=[
+ args.fruit_sources_dir,
+ '-DCMAKE_BUILD_TYPE=Release',
+ *additional_cmake_args,
+ ],
+ cwd=fruit_build_dir,
+ env=modified_env)
+ run_command('make', args=make_args, cwd=fruit_build_dir)
+ except Exception as e:
+ print('Exception while preparing for benchmarks with the compiler %s, with additional CMake args %s.\n%s\nGoing ahead with the rest.' % (compiler_executable_name, additional_cmake_args, traceback.format_exc()))
+ continue
for benchmark_definition in benchmark_definitions_with_current_config:
benchmark_index += 1
@@ -744,6 +810,7 @@ def main():
benchmark_class = {
'fruit_compile_time': FruitCompileTimeBenchmark,
'fruit_incremental_compile_time': FruitIncrementalCompileTimeBenchmark,
+ 'fruit_compile_memory': FruitCompileMemoryBenchmark,
'fruit_run_time': FruitRunTimeBenchmark,
'fruit_startup_time': FruitStartupTimeBenchmark,
'fruit_startup_time_with_normalized_component': FruitStartupTimeWithNormalizedComponentBenchmark,
@@ -758,6 +825,7 @@ def main():
benchmark_class = {
'boost_di_compile_time': BoostDiCompileTimeBenchmark,
'boost_di_incremental_compile_time': BoostDiIncrementalCompileTimeBenchmark,
+ 'boost_di_compile_memory': BoostDiCompileMemoryBenchmark,
'boost_di_run_time': BoostDiRunTimeBenchmark,
'boost_di_startup_time': BoostDiStartupTimeBenchmark,
'boost_di_executable_size': BoostDiExecutableSizeBenchmark,
@@ -770,18 +838,21 @@ def main():
benchmark_class = {
'simple_di_compile_time': SimpleDiCompileTimeBenchmark,
'simple_di_incremental_compile_time': SimpleDiIncrementalCompileTimeBenchmark,
+ 'simple_di_compile_memory': SimpleDiCompileMemoryBenchmark,
'simple_di_run_time': SimpleDiRunTimeBenchmark,
'simple_di_startup_time': SimpleDiStartupTimeBenchmark,
'simple_di_executable_size': SimpleDiExecutableSizeBenchmark,
'simple_di_executable_size_without_exceptions_and_rtti': SimpleDiExecutableSizeBenchmarkWithoutExceptionsAndRtti,
'simple_di_with_interfaces_compile_time': SimpleDiWithInterfacesCompileTimeBenchmark,
'simple_di_with_interfaces_incremental_compile_time': SimpleDiWithInterfacesIncrementalCompileTimeBenchmark,
+ 'simple_di_with_interfaces_compile_memory': SimpleDiWithInterfacesCompileMemoryBenchmark,
'simple_di_with_interfaces_run_time': SimpleDiWithInterfacesRunTimeBenchmark,
'simple_di_with_interfaces_startup_time': SimpleDiWithInterfacesStartupTimeBenchmark,
'simple_di_with_interfaces_executable_size': SimpleDiWithInterfacesExecutableSizeBenchmark,
'simple_di_with_interfaces_executable_size_without_exceptions_and_rtti': SimpleDiWithInterfacesExecutableSizeBenchmarkWithoutExceptionsAndRtti,
'simple_di_with_interfaces_and_new_delete_compile_time': SimpleDiWithInterfacesAndNewDeleteCompileTimeBenchmark,
'simple_di_with_interfaces_and_new_delete_incremental_compile_time': SimpleDiWithInterfacesAndNewDeleteIncrementalCompileTimeBenchmark,
+ 'simple_di_with_interfaces_and_new_delete_compile_memory': SimpleDiWithInterfacesAndNewDeleteCompileMemoryBenchmark,
'simple_di_with_interfaces_and_new_delete_run_time': SimpleDiWithInterfacesAndNewDeleteRunTimeBenchmark,
'simple_di_with_interfaces_and_new_delete_startup_time': SimpleDiWithInterfacesAndNewDeleteStartupTimeBenchmark,
'simple_di_with_interfaces_and_new_delete_executable_size': SimpleDiWithInterfacesAndNewDeleteExecutableSizeBenchmark,
@@ -795,11 +866,14 @@ def main():
if benchmark.describe() in previous_run_completed_benchmarks:
print("Skipping benchmark that was already run previously (due to --continue-benchmark):", benchmark.describe())
continue
-
- run_benchmark(benchmark,
- output_file=args.output_file,
- max_runs=global_definitions['max_runs'],
- timeout_hours=global_definitions['max_hours_per_combination'])
+
+ try:
+ run_benchmark(benchmark,
+ output_file=args.output_file,
+ max_runs=global_definitions['max_runs'],
+ timeout_hours=global_definitions['max_hours_per_combination'])
+ except Exception as e:
+ print('Exception while running benchmark: %s.\n%s\nGoing ahead with the rest.' % (benchmark.describe(), traceback.format_exc()))
if __name__ == "__main__":
diff --git a/extras/benchmark/suites/boost_di.yml b/extras/benchmark/suites/boost_di.yml
index 815991c..458d11e 100644
--- a/extras/benchmark/suites/boost_di.yml
+++ b/extras/benchmark/suites/boost_di.yml
@@ -19,18 +19,21 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-8"
- - "clang++-6.0"
+ - "g++-9"
+ - "clang++-10"
benchmarks:
- name:
- "boost_di_compile_time"
+ - "boost_di_compile_memory"
- "boost_di_incremental_compile_time"
- "boost_di_run_time"
+ - "boost_di_startup_time"
- "boost_di_executable_size"
loop_factor: 1.0
num_classes:
- 100
+ - 250
- 1000
compiler: *compilers
cxx_std: "c++14"
@@ -38,3 +41,18 @@ benchmarks:
- []
benchmark_generation_flags:
- []
+
+ - name:
+ - "boost_di_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes:
+ - 100
+ - 250
+ - 1000
+ compiler: *compilers
+ cxx_std: "c++14"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
+
diff --git a/extras/benchmark/suites/debug.yml b/extras/benchmark/suites/debug.yml
index 13d6c0b..c31d4d5 100644
--- a/extras/benchmark/suites/debug.yml
+++ b/extras/benchmark/suites/debug.yml
@@ -22,12 +22,12 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-7"
- - "clang++-4.0"
+ - "g++-9"
+ - "clang++-10"
gcc: &gcc
- - "g++-7"
+ - "g++-9"
clang: &clang
- - "clang++-4.0"
+ - "clang++-10"
benchmarks:
- name: "fruit_single_file_compile_time"
@@ -43,16 +43,19 @@ benchmarks:
- name:
- "new_delete_run_time"
- "simple_di_compile_time"
+ - "simple_di_compile_memory"
- "simple_di_incremental_compile_time"
- "simple_di_run_time"
- "simple_di_startup_time"
- "simple_di_executable_size"
- "simple_di_with_interfaces_compile_time"
+ - "simple_di_with_interfaces_compile_memory"
- "simple_di_with_interfaces_incremental_compile_time"
- "simple_di_with_interfaces_run_time"
- "simple_di_with_interfaces_startup_time"
- "simple_di_with_interfaces_executable_size"
- "simple_di_with_interfaces_and_new_delete_compile_time"
+ - "simple_di_with_interfaces_and_new_delete_compile_memory"
- "simple_di_with_interfaces_and_new_delete_incremental_compile_time"
- "simple_di_with_interfaces_and_new_delete_run_time"
- "simple_di_with_interfaces_and_new_delete_startup_time"
@@ -68,7 +71,22 @@ benchmarks:
- []
- name:
+ - "simple_di_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti"
+ loop_factor: 0.01
+ num_classes:
+ - 100
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
+
+ - name:
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
- "fruit_startup_time"
@@ -87,7 +105,22 @@ benchmarks:
- []
- name:
+ - "fruit_executable_size_without_exceptions_and_rtti"
+ loop_factor: 0.01
+ num_classes:
+ - 100
+ compiler: *gcc
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ - ['-DFRUIT_USES_BOOST=False', '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ - ["-DBUILD_SHARED_LIBS=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
+
+ - name:
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
- "fruit_startup_time"
@@ -104,7 +137,20 @@ benchmarks:
- []
- name:
+ - "fruit_executable_size_without_exceptions_and_rtti"
+ loop_factor: 0.01
+ num_classes:
+ - 100
+ compiler: *clang
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
+
+ - name:
- "boost_di_compile_time"
+ - "boost_di_compile_memory"
- "boost_di_incremental_compile_time"
- "boost_di_run_time"
- "boost_di_startup_time"
@@ -118,3 +164,15 @@ benchmarks:
- []
benchmark_generation_flags:
- []
+
+ - name:
+ - "boost_di_executable_size_without_exceptions_and_rtti"
+ loop_factor: 0.01
+ num_classes:
+ - 100
+ compiler: *compilers
+ cxx_std: "c++14"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
diff --git a/extras/benchmark/suites/fruit_full.yml b/extras/benchmark/suites/fruit_full.yml
index 32ac6d1..9709291 100644
--- a/extras/benchmark/suites/fruit_full.yml
+++ b/extras/benchmark/suites/fruit_full.yml
@@ -19,10 +19,11 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-8"
- - "clang++-6.0"
+ - "g++-9"
+ - "clang++-10"
num_classes: &num_classes
- 100
+ - 250
- 1000
benchmarks:
@@ -39,10 +40,12 @@ benchmarks:
- []
- name:
- - "new_delete_run_time"
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
+ - "fruit_startup_time"
+ - "fruit_startup_time_with_normalized_component"
- "fruit_executable_size"
loop_factor: 1.0
num_classes: *num_classes
@@ -54,9 +57,23 @@ benchmarks:
- []
- name:
+ - "fruit_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes: *num_classes
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
+
+ - name:
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
+ - "fruit_startup_time"
+ - "fruit_startup_time_with_normalized_component"
- "fruit_executable_size"
loop_factor: 1.0
num_classes: *num_classes
@@ -67,3 +84,15 @@ benchmarks:
- ["-DBUILD_SHARED_LIBS=False"]
benchmark_generation_flags:
- []
+
+ - name:
+ - "fruit_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes: *num_classes
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DFRUIT_USES_BOOST=False', '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ - ["-DBUILD_SHARED_LIBS=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
diff --git a/extras/benchmark/suites/fruit_mostly_full.yml b/extras/benchmark/suites/fruit_mostly_full.yml
index e212ac8..f1eac70 100644
--- a/extras/benchmark/suites/fruit_mostly_full.yml
+++ b/extras/benchmark/suites/fruit_mostly_full.yml
@@ -19,11 +19,10 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-8"
- - "clang++-6.0"
+ - "g++-9"
+ - "clang++-10"
num_classes: &num_classes
- 100
- - 1000
benchmarks:
- name: "fruit_single_file_compile_time"
@@ -38,10 +37,12 @@ benchmarks:
- []
- name:
- - "new_delete_run_time"
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
+ - "fruit_startup_time"
+ - "fruit_startup_time_with_normalized_component"
- "fruit_executable_size"
loop_factor: 1.0
num_classes: *num_classes
@@ -51,3 +52,14 @@ benchmarks:
- []
benchmark_generation_flags:
- []
+
+ - name:
+ - "fruit_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes: *num_classes
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
diff --git a/extras/benchmark/suites/fruit_quick.yml b/extras/benchmark/suites/fruit_quick.yml
index 002e7e8..fd64ae7 100644
--- a/extras/benchmark/suites/fruit_quick.yml
+++ b/extras/benchmark/suites/fruit_quick.yml
@@ -19,8 +19,8 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-6"
- - "clang++-4.0"
+ - "g++-9"
+ - "clang++-10"
num_classes: &num_classes
- 100
@@ -38,9 +38,13 @@ benchmarks:
- name:
- "fruit_compile_time"
+ - "fruit_compile_memory"
- "fruit_incremental_compile_time"
- "fruit_run_time"
+ - "fruit_startup_time"
+ - "fruit_startup_time_with_normalized_component"
- "fruit_executable_size"
+ - "fruit_executable_size_without_exceptions_and_rtti"
loop_factor: 1.0
num_classes: *num_classes
compiler: *compilers
diff --git a/extras/benchmark/suites/fruit_single.yml b/extras/benchmark/suites/fruit_single.yml
index d269da9..e030c5e 100644
--- a/extras/benchmark/suites/fruit_single.yml
+++ b/extras/benchmark/suites/fruit_single.yml
@@ -21,7 +21,7 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-7"
+ - "g++-9"
benchmarks:
- name:
diff --git a/extras/benchmark/suites/simple_di_full.yml b/extras/benchmark/suites/simple_di_full.yml
index 6ed8d0f..6c104aa 100644
--- a/extras/benchmark/suites/simple_di_full.yml
+++ b/extras/benchmark/suites/simple_di_full.yml
@@ -22,33 +22,52 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-7"
- - "clang++-4.0"
+ - "g++-9"
+ - "clang++-10"
num_classes: &num_classes
- 100
+ - 250
- 1000
benchmarks:
- name:
- "new_delete_run_time"
- "simple_di_compile_time"
+ - "simple_di_compile_memory"
- "simple_di_incremental_compile_time"
- "simple_di_run_time"
+ - "simple_di_startup_time"
- "simple_di_executable_size"
+ - "simple_di_with_interfaces_compile_memory"
- "simple_di_with_interfaces_compile_time"
- "simple_di_with_interfaces_incremental_compile_time"
- "simple_di_with_interfaces_run_time"
+ - "simple_di_with_interfaces_startup_time"
- "simple_di_with_interfaces_executable_size"
+ - "simple_di_with_interfaces_and_new_delete_compile_memory"
- "simple_di_with_interfaces_and_new_delete_compile_time"
- "simple_di_with_interfaces_and_new_delete_incremental_compile_time"
- "simple_di_with_interfaces_and_new_delete_run_time"
+ - "simple_di_with_interfaces_and_new_delete_startup_time"
- "simple_di_with_interfaces_and_new_delete_executable_size"
loop_factor: 1.0
- num_classes:
- - 100
+ num_classes: *num_classes
compiler: *compilers
cxx_std: "c++11"
additional_cmake_args:
- []
benchmark_generation_flags:
- []
+
+ - name:
+ - "simple_di_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes: *num_classes
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
diff --git a/extras/benchmark/suites/simple_di_mostly_full.yml b/extras/benchmark/suites/simple_di_mostly_full.yml
index a833652..7ab0d00 100644
--- a/extras/benchmark/suites/simple_di_mostly_full.yml
+++ b/extras/benchmark/suites/simple_di_mostly_full.yml
@@ -22,8 +22,8 @@ global:
# These values are ignored, they are here just to be referenced below.
constants:
compilers: &compilers
- - "g++-7"
- - "clang++-4.0"
+ - "g++-9"
+ - "clang++-10"
num_classes: &num_classes
- 100
@@ -31,16 +31,22 @@ benchmarks:
- name:
- "new_delete_run_time"
- "simple_di_compile_time"
+ - "simple_di_compile_memory"
- "simple_di_incremental_compile_time"
- "simple_di_run_time"
+ - "simple_di_startup_time"
- "simple_di_executable_size"
- "simple_di_with_interfaces_compile_time"
+ - "simple_di_with_interfaces_compile_memory"
- "simple_di_with_interfaces_incremental_compile_time"
- "simple_di_with_interfaces_run_time"
+ - "simple_di_with_interfaces_startup_time"
- "simple_di_with_interfaces_executable_size"
- "simple_di_with_interfaces_and_new_delete_compile_time"
+ - "simple_di_with_interfaces_and_new_delete_compile_memory"
- "simple_di_with_interfaces_and_new_delete_incremental_compile_time"
- "simple_di_with_interfaces_and_new_delete_run_time"
+ - "simple_di_with_interfaces_and_new_delete_startup_time"
- "simple_di_with_interfaces_and_new_delete_executable_size"
loop_factor: 1.0
num_classes:
@@ -51,3 +57,17 @@ benchmarks:
- []
benchmark_generation_flags:
- []
+
+ - name:
+ - "simple_di_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti"
+ - "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti"
+ loop_factor: 1.0
+ num_classes:
+ - 100
+ compiler: *compilers
+ cxx_std: "c++11"
+ additional_cmake_args:
+ - ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags:
+ - []
diff --git a/extras/benchmark/tables/fruit_internal.yml b/extras/benchmark/tables/fruit_internal.yml
index 48ac40e..dfc7a27 100644
--- a/extras/benchmark/tables/fruit_internal.yml
+++ b/extras/benchmark/tables/fruit_internal.yml
@@ -16,139 +16,283 @@ constants:
pretty_printer:
format_string: "%s"
+allowed_unused_benchmarks:
+ - new_delete_run_time
+ - fruit_single_file_compile_time
+
+allowed_unused_benchmark_results:
+ - total_max_ram_usage
+
tables:
- - name: "Fruit compile time (single file)"
+
+ # Fruit vs Boost.DI and "no DI"
+
+ - name: "Compile time (Clang)"
benchmark_filter:
- name: "fruit_single_file_compile_time"
benchmark_generation_flags: []
additional_cmake_args: []
- columns: *num_bindings_column
- rows: *compiler_name_row
+ compiler: "clang++-10"
+ name: [
+ "fruit_compile_time",
+ "boost_di_compile_time",
+ "simple_di_compile_time",
+ "simple_di_with_interfaces_compile_time",
+ "simple_di_with_interfaces_and_new_delete_compile_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_time": "Fruit"
+ "boost_di_compile_time": "Boost.DI"
+ "simple_di_compile_time": "Simple DI"
+ "simple_di_with_interfaces_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_time": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
results:
dimension: "compile_time"
unit: "seconds"
-
- - name: "Fruit compile time"
+
+ - name: "Compile time (GCC)"
benchmark_filter:
- name: "fruit_compile_time"
benchmark_generation_flags: []
additional_cmake_args: []
+ compiler: "g++-9"
+ name: [
+ "fruit_compile_time",
+ "boost_di_compile_time",
+ "simple_di_compile_time",
+ "simple_di_with_interfaces_compile_time",
+ "simple_di_with_interfaces_and_new_delete_compile_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_time": "Fruit"
+ "boost_di_compile_time": "Boost.DI"
+ "simple_di_compile_time": "Simple DI"
+ "simple_di_with_interfaces_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_time": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
dimension: "compile_time"
unit: "seconds"
- - name: "Fruit incremental compile time"
+ - name: "Incremental compile time (Clang)"
benchmark_filter:
- name: "fruit_incremental_compile_time"
benchmark_generation_flags: []
additional_cmake_args: []
+ compiler: "clang++-10"
+ name: [
+ "fruit_incremental_compile_time",
+ "boost_di_incremental_compile_time",
+ "simple_di_incremental_compile_time",
+ "simple_di_with_interfaces_incremental_compile_time",
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_incremental_compile_time": "Fruit"
+ "boost_di_incremental_compile_time": "Boost.DI"
+ "simple_di_incremental_compile_time": "Simple DI"
+ "simple_di_with_interfaces_incremental_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "compile_time"
+ dimension: "incremental_compile_time"
unit: "seconds"
- - name: "Fruit full injection time"
+ - name: "Incremental compile time (GCC)"
benchmark_filter:
- name: "fruit_run_time"
benchmark_generation_flags: []
additional_cmake_args: []
+ compiler: "g++-9"
+ name: [
+ "fruit_incremental_compile_time",
+ "boost_di_incremental_compile_time",
+ "simple_di_incremental_compile_time",
+ "simple_di_with_interfaces_incremental_compile_time",
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_incremental_compile_time": "Fruit"
+ "boost_di_incremental_compile_time": "Boost.DI"
+ "simple_di_incremental_compile_time": "Simple DI"
+ "simple_di_with_interfaces_incremental_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "Full injection time"
+ dimension: "incremental_compile_time"
unit: "seconds"
- - name: "Fruit component normalization time"
+ - name: "Compile memory (Clang)"
benchmark_filter:
- name: "fruit_run_time"
benchmark_generation_flags: []
additional_cmake_args: []
+ compiler: "clang++-10"
+ name: [
+ "fruit_compile_memory",
+ "boost_di_compile_memory",
+ "simple_di_compile_memory",
+ "simple_di_with_interfaces_compile_memory",
+ "simple_di_with_interfaces_and_new_delete_compile_memory",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_memory": "Fruit"
+ "boost_di_compile_memory": "Boost.DI"
+ "simple_di_compile_memory": "Simple DI"
+ "simple_di_with_interfaces_compile_memory": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_memory": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "componentNormalizationTime"
- unit: "seconds"
+ dimension: "max_ram_usage"
+ unit: "bytes"
- - name: "Fruit setup time"
+ - name: "Compile memory (GCC)"
benchmark_filter:
- name: "fruit_run_time"
benchmark_generation_flags: []
additional_cmake_args: []
+ compiler: "g++-9"
+ name: [
+ "fruit_compile_memory",
+ "boost_di_compile_memory",
+ "simple_di_compile_memory",
+ "simple_di_with_interfaces_compile_memory",
+ "simple_di_with_interfaces_and_new_delete_compile_memory",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_memory": "Fruit"
+ "boost_di_compile_memory": "Boost.DI"
+ "simple_di_compile_memory": "Simple DI"
+ "simple_di_with_interfaces_compile_memory": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_memory": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "Total for setup"
- unit: "seconds"
+ dimension: "max_ram_usage"
+ unit: "bytes"
- - name: "Fruit per-request time"
+ - name: "Startup time (Clang)"
benchmark_filter:
- name: "fruit_run_time"
+ compiler: "clang++-10"
benchmark_generation_flags: []
additional_cmake_args: []
+ name: [
+ "fruit_startup_time",
+ "boost_di_startup_time",
+ "simple_di_startup_time",
+ "simple_di_with_interfaces_startup_time",
+ "simple_di_with_interfaces_and_new_delete_startup_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_startup_time": "Fruit"
+ "boost_di_startup_time": "Boost.DI"
+ "simple_di_startup_time": "Simple DI"
+ "simple_di_with_interfaces_startup_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "Total per request"
+ dimension: "startup_time"
unit: "seconds"
-
- - name: "New/delete time"
- benchmark_filter:
- name: "new_delete_run_time"
+
+ - name: "Startup time (GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
benchmark_generation_flags: []
additional_cmake_args: []
+ name: [
+ "fruit_startup_time",
+ "boost_di_startup_time",
+ "simple_di_startup_time",
+ "simple_di_with_interfaces_startup_time",
+ "simple_di_with_interfaces_and_new_delete_startup_time",
+ ]
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_startup_time": "Fruit"
+ "boost_di_startup_time": "Boost.DI"
+ "simple_di_startup_time": "Simple DI"
+ "simple_di_with_interfaces_startup_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time": "Simple DI w/ interfaces, new/delete"
columns: *num_classes_column
- rows: *compiler_name_row
results:
- dimension: "Total"
+ dimension: "startup_time"
unit: "seconds"
-
- - name: "Compile time (100 classes)"
+
+ - name: "Startup time with normalized component (Clang)"
benchmark_filter:
- num_classes: 100
+ compiler: "clang++-10"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ name: [
+ "fruit_startup_time_with_normalized_component",
+ "boost_di_startup_time_with_normalized_component",
+ "simple_di_startup_time_with_normalized_component",
+ "simple_di_with_interfaces_startup_time_with_normalized_component",
+ "simple_di_with_interfaces_and_new_delete_startup_time_with_normalized_component",
+ ]
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
- "fruit_compile_time": "Fruit"
- "boost_di_compile_time": "Boost.DI"
- "simple_di_incremental_compile_time": "Simple DI"
- "simple_di_with_interfaces_incremental_compile_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ "fruit_startup_time_with_normalized_component": "Fruit"
+ "boost_di_startup_time_with_normalized_component": "Boost.DI"
+ "simple_di_startup_time_with_normalized_component": "Simple DI"
+ "simple_di_with_interfaces_startup_time_with_normalized_component": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time_with_normalized_component": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
results:
- dimension: "compile_time"
+ dimension: "fruit_startup_time_with_normalized_component"
unit: "seconds"
-
- - name: "Incremental compile time (100 classes)"
+
+ - name: "Startup time with normalized component (GCC)"
benchmark_filter:
- num_classes: 100
+ compiler: "g++-9"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ name: [
+ "fruit_startup_time_with_normalized_component",
+ "boost_di_startup_time_with_normalized_component",
+ "simple_di_startup_time_with_normalized_component",
+ "simple_di_with_interfaces_startup_time_with_normalized_component",
+ "simple_di_with_interfaces_and_new_delete_startup_time_with_normalized_component",
+ ]
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
- "fruit_incremental_compile_time": "Fruit"
- "boost_di_incremental_compile_time": "Boost.DI"
- "simple_di_incremental_compile_time": "Simple DI"
- "simple_di_with_interfaces_incremental_compile_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ "fruit_startup_time_with_normalized_component": "Fruit"
+ "boost_di_startup_time_with_normalized_component": "Boost.DI"
+ "simple_di_startup_time_with_normalized_component": "Simple DI"
+ "simple_di_with_interfaces_startup_time_with_normalized_component": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time_with_normalized_component": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
results:
- dimension: "compile_time"
+ dimension: "fruit_startup_time_with_normalized_component"
unit: "seconds"
- - name: "Fruit full injection time (100 classes)"
+ - name: "Component normalization time (Clang)"
benchmark_filter:
- num_classes: 100
+ compiler: "clang++-10"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
@@ -157,17 +301,17 @@ tables:
"simple_di_incremental_run_time": "Simple DI"
"simple_di_with_interfaces_incremental_run_time": "Simple DI w/ interfaces"
"simple_di_with_interfaces_and_new_delete_incremental_run_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ columns: *num_classes_column
results:
- dimension: "Full injection time"
+ dimension: "componentNormalizationTime"
unit: "seconds"
- - name: "Fruit component normalization time (100 classes)"
+ - name: "Component normalization time (GCC)"
benchmark_filter:
- num_classes: 100
+ compiler: "g++-9"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
@@ -176,65 +320,427 @@ tables:
"simple_di_incremental_run_time": "Simple DI"
"simple_di_with_interfaces_incremental_run_time": "Simple DI w/ interfaces"
"simple_di_with_interfaces_and_new_delete_incremental_run_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ columns: *num_classes_column
results:
dimension: "componentNormalizationTime"
unit: "seconds"
-
- - name: "Setup time (100 classes)"
+ - name: "Per-request time (Clang)"
benchmark_filter:
- num_classes: 100
+ compiler: "clang++-10"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
"fruit_run_time": "Fruit"
"boost_di_run_time": "Boost.DI"
- "simple_di_incremental_run_time": "Simple DI"
- "simple_di_with_interfaces_incremental_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_incremental_run_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ "simple_di_run_time": "Simple DI"
+ "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
results:
- dimension: "Total for setup"
+ dimension: "Total per request"
unit: "seconds"
- - name: "Per-request time (100 classes)"
+ - name: "Per-request time (GCC)"
benchmark_filter:
- num_classes: 100
+ compiler: "g++-9"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
"fruit_run_time": "Fruit"
"boost_di_run_time": "Boost.DI"
- "simple_di_incremental_run_time": "Simple DI"
- "simple_di_with_interfaces_incremental_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_incremental_run_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ "simple_di_run_time": "Simple DI"
+ "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
results:
dimension: "Total per request"
unit: "seconds"
-
- - name: "Executable size (stripped, 100 classes)"
+
+ - name: "Executable size (stripped, Clang)"
benchmark_filter:
- num_classes: 100
+ compiler: "clang++-10"
benchmark_generation_flags: []
additional_cmake_args: []
- columns:
+ rows:
dimension: "name"
pretty_printer:
fixed_map:
"fruit_executable_size": "Fruit"
"boost_di_executable_size": "Boost.DI"
- "simple_di_incremental_run_time": "Simple DI"
- "simple_di_with_interfaces_incremental_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_incremental_run_time": "Simple DI w/ interfaces, new/delete"
- rows: *compiler_name_row
+ "simple_di_executable_size": "Simple DI"
+ "simple_di_with_interfaces_executable_size": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ additional_cmake_args: []
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size": "Fruit"
+ "boost_di_executable_size": "Boost.DI"
+ "simple_di_executable_size": "Simple DI"
+ "simple_di_with_interfaces_executable_size": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, no exceptions/RTTI, Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ additional_cmake_args: ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size_without_exceptions_and_rtti": "Fruit"
+ "boost_di_executable_size_without_exceptions_and_rtti": "Boost.DI"
+ "simple_di_executable_size_without_exceptions_and_rtti": "Simple DI"
+ "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, no exceptions/RTTI, GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ additional_cmake_args: ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ rows:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size_without_exceptions_and_rtti": "Fruit"
+ "boost_di_executable_size_without_exceptions_and_rtti": "Boost.DI"
+ "simple_di_executable_size_without_exceptions_and_rtti": "Simple DI"
+ "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces, new/delete"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ # Fruit: performance by default and with various compiler options.
+
+ - name: "Fruit compile time (Clang)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "clang++-10"
+ name: "fruit_compile_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "compile_time"
+ unit: "seconds"
+
+ - name: "Fruit compile time (GCC)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "g++-9"
+ name: "fruit_compile_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "compile_time"
+ unit: "seconds"
+
+ - name: "Fruit incremental compile time (Clang)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "clang++-10"
+ name: "fruit_incremental_compile_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "incremental_compile_time"
+ unit: "seconds"
+
+ - name: "Fruit incremental compile time (GCC)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "g++-9"
+ name: "fruit_incremental_compile_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "incremental_compile_time"
+ unit: "seconds"
+
+ - name: "Fruit compile memory (Clang)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "clang++-10"
+ name: "fruit_compile_memory"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "max_ram_usage"
+ unit: "bytes"
+
+ - name: "Fruit compile memory (GCC)"
+ benchmark_filter:
+ benchmark_generation_flags: []
+ compiler: "g++-9"
+ name: "fruit_compile_memory"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "max_ram_usage"
+ unit: "bytes"
+
+ - name: "Fruit startup time (Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ name: "fruit_startup_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Fruit startup time (GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ name: "fruit_startup_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Fruit startup time with normalized component (Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ name: "fruit_startup_time_with_normalized_component"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Fruit startup time with normalized component (GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ name: "fruit_startup_time_with_normalized_component"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Fruit component normalization time (Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "componentNormalizationTime"
+ unit: "seconds"
+
+ - name: "Fruit component normalization time (GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "componentNormalizationTime"
+ unit: "seconds"
+
+ - name: "Fruit per-request time (Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ name: "fruit_run_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "Total per request"
+ unit: "seconds"
+
+ - name: "Fruit per-request time (GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ name: "fruit_run_time"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "Total per request"
+ unit: "seconds"
+
+ - name: "Fruit executable size (stripped, Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ name: "fruit_executable_size"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Fruit executable size (stripped, GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ name: "fruit_executable_size"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple []: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False"]: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False"]: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Fruit executable size (stripped, no exceptions/RTTI, Clang)"
+ benchmark_filter:
+ compiler: "clang++-10"
+ benchmark_generation_flags: []
+ name: "fruit_executable_size_without_exceptions_and_rtti"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "without boost"
+ columns: *num_classes_column
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Fruit executable size (stripped, no exceptions/RTTI, GCC)"
+ benchmark_filter:
+ compiler: "g++-9"
+ benchmark_generation_flags: []
+ name: "fruit_executable_size_without_exceptions_and_rtti"
+ rows:
+ dimension: "additional_cmake_args"
+ pretty_printer:
+ fixed_map:
+ !!python/tuple ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "(defaults)"
+ !!python/tuple ["-DBUILD_SHARED_LIBS=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "statically linked"
+ !!python/tuple ["-DFRUIT_USES_BOOST=False", '-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']: "without boost"
+ columns: *num_classes_column
results:
dimension: "num_bytes"
unit: "bytes"
diff --git a/extras/benchmark/tables/fruit_wiki.yml b/extras/benchmark/tables/fruit_wiki.yml
index 0af3b3e..28bdccf 100644
--- a/extras/benchmark/tables/fruit_wiki.yml
+++ b/extras/benchmark/tables/fruit_wiki.yml
@@ -41,26 +41,15 @@ tables:
dimension: "compile_time"
unit: "seconds"
- - name: "Fruit full injection time"
+ - name: "Fruit startup time"
benchmark_filter:
- name: "fruit_run_time"
+ name: "fruit_startup_time"
additional_cmake_args: []
benchmark_generation_flags: []
columns: *num_classes_column
rows: *compiler_name_row
results:
- dimension: "Full injection time"
- unit: "seconds"
-
- - name: "Fruit setup time"
- benchmark_filter:
- name: "fruit_run_time"
- additional_cmake_args: []
- benchmark_generation_flags: []
- columns: *num_classes_column
- rows: *compiler_name_row
- results:
- dimension: "Total for setup"
+ dimension: "startup_time"
unit: "seconds"
- name: "Fruit per-request time"
@@ -92,6 +81,39 @@ tables:
num_classes: 100
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_compile_time",
+ "boost_di_compile_time",
+ "simple_di_compile_time",
+ "simple_di_with_interfaces_compile_time",
+ "simple_di_with_interfaces_and_new_delete_compile_time",
+ ]
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_time": "Fruit"
+ "boost_di_compile_time": "Boost.DI"
+ "simple_di_compile_time": "Simple DI"
+ "simple_di_with_interfaces_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_time": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "compile_time"
+ unit: "seconds"
+
+ - name: "Compile time (250 classes)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ name: [
+ "fruit_compile_time",
+ "boost_di_compile_time",
+ "simple_di_compile_time",
+ "simple_di_with_interfaces_compile_time",
+ "simple_di_with_interfaces_and_new_delete_compile_time",
+ ]
columns:
dimension: "name"
pretty_printer:
@@ -111,6 +133,13 @@ tables:
num_classes: 1000
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_compile_time",
+ "boost_di_compile_time",
+ "simple_di_compile_time",
+ "simple_di_with_interfaces_compile_time",
+ "simple_di_with_interfaces_and_new_delete_compile_time",
+ ]
columns:
dimension: "name"
pretty_printer:
@@ -130,6 +159,13 @@ tables:
num_classes: 100
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_incremental_compile_time",
+ "boost_di_incremental_compile_time",
+ "simple_di_incremental_compile_time",
+ "simple_di_with_interfaces_incremental_compile_time",
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time",
+ ]
columns:
dimension: "name"
pretty_printer:
@@ -141,7 +177,33 @@ tables:
"simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "compile_time"
+ dimension: "incremental_compile_time"
+ unit: "seconds"
+
+ - name: "Incremental compile time (250 classes)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ name: [
+ "fruit_incremental_compile_time",
+ "boost_di_incremental_compile_time",
+ "simple_di_incremental_compile_time",
+ "simple_di_with_interfaces_incremental_compile_time",
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time",
+ ]
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_incremental_compile_time": "Fruit"
+ "boost_di_incremental_compile_time": "Boost.DI"
+ "simple_di_incremental_compile_time": "Simple DI"
+ "simple_di_with_interfaces_incremental_compile_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "incremental_compile_time"
unit: "seconds"
- name: "Incremental compile time (1000 classes)"
@@ -149,6 +211,13 @@ tables:
num_classes: 1000
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_incremental_compile_time",
+ "boost_di_incremental_compile_time",
+ "simple_di_incremental_compile_time",
+ "simple_di_with_interfaces_incremental_compile_time",
+ "simple_di_with_interfaces_and_new_delete_incremental_compile_time",
+ ]
columns:
dimension: "name"
pretty_printer:
@@ -160,48 +229,88 @@ tables:
"simple_di_with_interfaces_and_new_delete_incremental_compile_time": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "compile_time"
+ dimension: "incremental_compile_time"
unit: "seconds"
- - name: "Full injection time (100 classes)"
+ - name: "Compile memory (100 classes)"
benchmark_filter:
num_classes: 100
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_compile_memory",
+ "boost_di_compile_memory",
+ "simple_di_compile_memory",
+ "simple_di_with_interfaces_compile_memory",
+ "simple_di_with_interfaces_and_new_delete_compile_memory",
+ ]
columns:
dimension: "name"
pretty_printer:
fixed_map:
- "fruit_run_time": "Fruit"
- "boost_di_run_time": "Boost.DI"
- "simple_di_run_time": "Simple DI"
- "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ "fruit_compile_memory": "Fruit"
+ "boost_di_compile_memory": "Boost.DI"
+ "simple_di_compile_memory": "Simple DI"
+ "simple_di_with_interfaces_compile_memory": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_memory": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "Full injection time"
- unit: "seconds"
+ dimension: "max_ram_usage"
+ unit: "bytes"
+
+ - name: "Compile memory (250 classes)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ name: [
+ "fruit_compile_memory",
+ "boost_di_compile_memory",
+ "simple_di_compile_memory",
+ "simple_di_with_interfaces_compile_memory",
+ "simple_di_with_interfaces_and_new_delete_compile_memory",
+ ]
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_compile_memory": "Fruit"
+ "boost_di_compile_memory": "Boost.DI"
+ "simple_di_compile_memory": "Simple DI"
+ "simple_di_with_interfaces_compile_memory": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_memory": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "max_ram_usage"
+ unit: "bytes"
- - name: "Full injection time (1000 classes)"
+ - name: "Compile memory (1000 classes)"
benchmark_filter:
num_classes: 1000
additional_cmake_args: []
benchmark_generation_flags: []
+ name: [
+ "fruit_compile_memory",
+ "boost_di_compile_memory",
+ "simple_di_compile_memory",
+ "simple_di_with_interfaces_compile_memory",
+ "simple_di_with_interfaces_and_new_delete_compile_memory",
+ ]
columns:
dimension: "name"
pretty_printer:
fixed_map:
- "fruit_run_time": "Fruit"
- "boost_di_run_time": "Boost.DI"
- "simple_di_run_time": "Simple DI"
- "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ "fruit_compile_memory": "Fruit"
+ "boost_di_compile_memory": "Boost.DI"
+ "simple_di_compile_memory": "Simple DI"
+ "simple_di_with_interfaces_compile_memory": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_compile_memory": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "Full injection time"
- unit: "seconds"
+ dimension: "max_ram_usage"
+ unit: "bytes"
- - name: "Setup time (100 classes)"
+ - name: "Startup time (100 classes)"
benchmark_filter:
num_classes: 100
additional_cmake_args: []
@@ -210,17 +319,38 @@ tables:
dimension: "name"
pretty_printer:
fixed_map:
- "fruit_run_time": "Fruit"
- "boost_di_run_time": "Boost.DI"
- "simple_di_run_time": "Simple DI"
- "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ "fruit_startup_time": "Fruit"
+ "fruit_startup_time_with_normalized_component": "Fruit (with normalized component)"
+ "boost_di_startup_time": "Boost.DI"
+ "simple_di_startup_time": "Simple DI"
+ "simple_di_with_interfaces_startup_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "Total for setup"
+ dimension: "startup_time"
unit: "seconds"
-
- - name: "Setup time (1000 classes)"
+
+ - name: "Startup time (250 classes)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_startup_time": "Fruit"
+ "fruit_startup_time_with_normalized_component": "Fruit (with normalized component)"
+ "boost_di_startup_time": "Boost.DI"
+ "simple_di_startup_time": "Simple DI"
+ "simple_di_with_interfaces_startup_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Startup time (1000 classes)"
benchmark_filter:
num_classes: 1000
additional_cmake_args: []
@@ -229,6 +359,26 @@ tables:
dimension: "name"
pretty_printer:
fixed_map:
+ "fruit_startup_time": "Fruit"
+ "fruit_startup_time_with_normalized_component": "Fruit (with normalized component)"
+ "boost_di_startup_time": "Boost.DI"
+ "simple_di_startup_time": "Simple DI"
+ "simple_di_with_interfaces_startup_time": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_startup_time": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "startup_time"
+ unit: "seconds"
+
+ - name: "Per-request time (100 classes)"
+ benchmark_filter:
+ num_classes: 100
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
"fruit_run_time": "Fruit"
"boost_di_run_time": "Boost.DI"
"simple_di_run_time": "Simple DI"
@@ -236,12 +386,12 @@ tables:
"simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
- dimension: "Total for setup"
+ dimension: "Total per request"
unit: "seconds"
- - name: "Per-request time (100 classes)"
+ - name: "Per-request time (250 classes)"
benchmark_filter:
- num_classes: 100
+ num_classes: 250
additional_cmake_args: []
benchmark_generation_flags: []
columns:
@@ -288,9 +438,28 @@ tables:
fixed_map:
"fruit_executable_size": "Fruit"
"boost_di_executable_size": "Boost.DI"
- "simple_di_run_time": "Simple DI"
- "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ "simple_di_executable_size": "Simple DI"
+ "simple_di_with_interfaces_executable_size": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, 250 classes)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: []
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size": "Fruit"
+ "boost_di_executable_size": "Boost.DI"
+ "simple_di_executable_size": "Simple DI"
+ "simple_di_with_interfaces_executable_size": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
dimension: "num_bytes"
@@ -307,9 +476,67 @@ tables:
fixed_map:
"fruit_executable_size": "Fruit"
"boost_di_executable_size": "Boost.DI"
- "simple_di_run_time": "Simple DI"
- "simple_di_with_interfaces_run_time": "Simple DI w/ interfaces"
- "simple_di_with_interfaces_and_new_delete_run_time": "Simple DI w/ interfaces, new/delete"
+ "simple_di_executable_size": "Simple DI"
+ "simple_di_with_interfaces_executable_size": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+
+ - name: "Executable size (stripped, 100 classes, no exceptions/rtti)"
+ benchmark_filter:
+ num_classes: 100
+ additional_cmake_args: ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size_without_exceptions_and_rtti": "Fruit"
+ "boost_di_executable_size_without_exceptions_and_rtti": "Boost.DI"
+ "simple_di_executable_size_without_exceptions_and_rtti": "Simple DI"
+ "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, 250 classes, no exceptions/rtti)"
+ benchmark_filter:
+ num_classes: 250
+ additional_cmake_args: ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size_without_exceptions_and_rtti": "Fruit"
+ "boost_di_executable_size_without_exceptions_and_rtti": "Boost.DI"
+ "simple_di_executable_size_without_exceptions_and_rtti": "Simple DI"
+ "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces, new/delete"
+ rows: *compiler_name_row
+ results:
+ dimension: "num_bytes"
+ unit: "bytes"
+
+ - name: "Executable size (stripped, 1000 classes, no exceptions/rtti)"
+ benchmark_filter:
+ num_classes: 1000
+ additional_cmake_args: ['-DCMAKE_CXX_FLAGS=-fno-exceptions -fno-rtti']
+ benchmark_generation_flags: []
+ columns:
+ dimension: "name"
+ pretty_printer:
+ fixed_map:
+ "fruit_executable_size_without_exceptions_and_rtti": "Fruit"
+ "boost_di_executable_size_without_exceptions_and_rtti": "Boost.DI"
+ "simple_di_executable_size_without_exceptions_and_rtti": "Simple DI"
+ "simple_di_with_interfaces_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces"
+ "simple_di_with_interfaces_and_new_delete_executable_size_without_exceptions_and_rtti": "Simple DI w/ interfaces, new/delete"
rows: *compiler_name_row
results:
dimension: "num_bytes"
@@ -338,10 +565,10 @@ tables:
dimension: "compile_time"
unit: "seconds"
- - name: "Full injection time (100 classes)"
+ - name: "Startup time (100 classes)"
benchmark_filter:
num_classes: 100
- name: "fruit_run_time"
+ name: "fruit_startup_time"
benchmark_generation_flags: []
columns:
dimension: "additional_cmake_args"
@@ -355,13 +582,13 @@ tables:
to: "Statically-linking with Fruit"
rows: *compiler_name_row
results:
- dimension: "Full injection time"
+ dimension: "startup_time"
unit: "seconds"
- - name: "Setup time (100 classes)"
+ - name: "Startup time (100 classes)"
benchmark_filter:
num_classes: 100
- name: "fruit_run_time"
+ name: "fruit_startup_time"
benchmark_generation_flags: []
columns:
dimension: "additional_cmake_args"
@@ -375,7 +602,7 @@ tables:
to: "Statically-linking with Fruit"
rows: *compiler_name_row
results:
- dimension: "Total for setup"
+ dimension: "startup_time"
unit: "seconds"
- name: "Per-request time (100 classes)"
diff --git a/extras/dockerfiles/.dockerignore b/extras/dockerfiles/.dockerignore
new file mode 100644
index 0000000..4e1954c
--- /dev/null
+++ b/extras/dockerfiles/.dockerignore
@@ -0,0 +1,2 @@
+Dockerfile.*
+rebuild_all.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-16.04 b/extras/dockerfiles/Dockerfile.ubuntu-16.04
deleted file mode 100644
index b53b883..0000000
--- a/extras/dockerfiles/Dockerfile.ubuntu-16.04
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:16.04
-MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-
-COPY ubuntu-16.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu-16.04_install.sh /
-
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu-16.04_install.sh && \
- bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-17.04 b/extras/dockerfiles/Dockerfile.ubuntu-17.04
deleted file mode 100644
index ee50dcc..0000000
--- a/extras/dockerfiles/Dockerfile.ubuntu-17.04
+++ /dev/null
@@ -1,10 +0,0 @@
-FROM ubuntu:17.04
-MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-
-COPY ubuntu-17.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu-17.04_install.sh /
-
-RUN sed -i -re 's/([a-z]{2}\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list; \
- bash -x /common_install.sh && \
- bash -x /ubuntu-17.04_install.sh && \
- bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-18.04 b/extras/dockerfiles/Dockerfile.ubuntu-18.04
index ec5d5cb..d458bb4 100644
--- a/extras/dockerfiles/Dockerfile.ubuntu-18.04
+++ b/extras/dockerfiles/Dockerfile.ubuntu-18.04
@@ -1,9 +1,53 @@
FROM ubuntu:18.04
MAINTAINER Marco Poletti <poletti.marco@gmail.com>
+COPY common_install.sh common_cleanup.sh /
+
+RUN bash -x /common_install.sh
+RUN apt-get install -y --no-install-recommends curl
+
+# For the Bazel repository
+RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
+
+RUN echo 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8' >> /etc/apt/sources.list.d/bazel.list
+
COPY ubuntu-18.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu-18.04_install.sh /
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu-18.04_install.sh && \
- bash -x /common_cleanup.sh
+RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys F23C5A6CF475977595C89F51BA6932366A755776
+
+RUN apt-get update -qq
+
+RUN apt-get remove -y python3-pip
+RUN python3 -m easy_install pip
+
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-8 \
+ g++-7 \
+ g++-6 \
+ g++-5 \
+ clang-3.9 \
+ clang-4.0 \
+ clang-5.0 \
+ clang-6.0 \
+ clang-7 \
+ clang-8 \
+ clang-9 \
+ clang-10 \
+ bazel \
+ git \
+ python3.8 \
+ clang-tidy \
+ clang-format
+
+RUN python3.8 -m easy_install pip
+
+RUN pip3 install absl-py
+RUN pip3 install bidict
+RUN pip3 install pytest
+RUN pip3 install pytest-xdist
+RUN pip3 install sh
+RUN pip3 install setuptools
+RUN pip3 install networkx
+RUN pip3 install wheel
+
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-18.10 b/extras/dockerfiles/Dockerfile.ubuntu-18.10
deleted file mode 100644
index 09bd008..0000000
--- a/extras/dockerfiles/Dockerfile.ubuntu-18.10
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:18.10
-MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-
-COPY ubuntu-18.10_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu-18.10_install.sh /
-
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu-18.10_install.sh && \
- bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-19.04 b/extras/dockerfiles/Dockerfile.ubuntu-19.04
deleted file mode 100644
index 7939990..0000000
--- a/extras/dockerfiles/Dockerfile.ubuntu-19.04
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:19.04
-MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-
-COPY ubuntu-19.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu-19.04_install.sh /
-
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu-19.04_install.sh && \
- bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-19.10 b/extras/dockerfiles/Dockerfile.ubuntu-19.10
new file mode 100644
index 0000000..ca6be96
--- /dev/null
+++ b/extras/dockerfiles/Dockerfile.ubuntu-19.10
@@ -0,0 +1,40 @@
+FROM ubuntu:19.10
+MAINTAINER Marco Poletti <poletti.marco@gmail.com>
+
+COPY common_install.sh common_cleanup.sh /
+
+RUN bash -x /common_install.sh
+
+COPY ubuntu-19.10_custom.list /etc/apt/sources.list.d/
+
+RUN apt-get update
+
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-7 \
+ g++-8 \
+ g++-9 \
+ clang-6.0 \
+ clang-7 \
+ clang-8 \
+ clang-9 \
+ clang-10 \
+ python3-sh \
+ python3-typed-ast \
+ python3-pip \
+ python3-setuptools \
+ python3-networkx \
+ clang-tidy \
+ clang-format
+
+RUN pip3 install --upgrade pip
+
+RUN pip3 install absl-py
+RUN pip3 install bidict
+RUN pip3 install pytest
+RUN pip3 install pytest-xdist
+RUN pip3 install sh
+RUN pip3 install setuptools
+RUN pip3 install networkx
+RUN pip3 install wheel
+
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-20.04 b/extras/dockerfiles/Dockerfile.ubuntu-20.04
new file mode 100644
index 0000000..3ce7d9c
--- /dev/null
+++ b/extras/dockerfiles/Dockerfile.ubuntu-20.04
@@ -0,0 +1,41 @@
+FROM ubuntu:20.04
+MAINTAINER Marco Poletti <poletti.marco@gmail.com>
+
+COPY common_install.sh common_cleanup.sh /
+
+RUN bash -x /common_install.sh
+
+COPY ubuntu-20.04_custom.list /etc/apt/sources.list.d/
+
+RUN apt-get update
+
+RUN apt-get remove -y python3-pip
+RUN python3 -m easy_install pip
+
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-7 \
+ g++-8 \
+ g++-9 \
+ g++-10 \
+ clang-6.0 \
+ clang-7 \
+ clang-8 \
+ clang-9 \
+ clang-10 \
+ python3.8 \
+ python3.8-distutils \
+ clang-tidy \
+ clang-format
+
+RUN python3.8 -m easy_install pip
+
+RUN pip3 install absl-py
+RUN pip3 install bidict
+RUN pip3 install pytest
+RUN pip3 install pytest-xdist
+RUN pip3 install sh
+RUN pip3 install setuptools
+RUN pip3 install networkx
+RUN pip3 install wheel
+
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu-20.10 b/extras/dockerfiles/Dockerfile.ubuntu-20.10
new file mode 100644
index 0000000..6b4e52c
--- /dev/null
+++ b/extras/dockerfiles/Dockerfile.ubuntu-20.10
@@ -0,0 +1,40 @@
+FROM ubuntu:20.10
+MAINTAINER Marco Poletti <poletti.marco@gmail.com>
+
+COPY common_install.sh common_cleanup.sh /
+
+RUN bash -x /common_install.sh
+
+COPY ubuntu-20.10_custom.list /etc/apt/sources.list.d/
+
+RUN apt-get update
+
+RUN apt-get remove -y python3-pip
+RUN python3 -m easy_install pip
+
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-7 \
+ g++-8 \
+ g++-9 \
+ g++-10 \
+ clang-8 \
+ clang-9 \
+ clang-10 \
+ clang-11 \
+ python3.8 \
+ python3.8-distutils \
+ clang-tidy \
+ clang-format
+
+RUN python3.8 -m easy_install pip
+
+RUN pip3 install absl-py
+RUN pip3 install bidict
+RUN pip3 install pytest
+RUN pip3 install pytest-xdist
+RUN pip3 install sh
+RUN pip3 install setuptools
+RUN pip3 install networkx
+RUN pip3 install wheel
+
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu_arm-16.04 b/extras/dockerfiles/Dockerfile.ubuntu_arm-16.04
deleted file mode 100644
index 35342b9..0000000
--- a/extras/dockerfiles/Dockerfile.ubuntu_arm-16.04
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM multiarch/ubuntu-core:arm64-xenial
-MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-
-COPY ubuntu_arm-16.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu_arm-16.04_install.sh /
-
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu_arm-16.04_install.sh && \
- bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu_arm-18.04 b/extras/dockerfiles/Dockerfile.ubuntu_arm-18.04
index 852abb5..8ecab4d 100644
--- a/extras/dockerfiles/Dockerfile.ubuntu_arm-18.04
+++ b/extras/dockerfiles/Dockerfile.ubuntu_arm-18.04
@@ -1,9 +1,20 @@
FROM multiarch/ubuntu-core:arm64-bionic
MAINTAINER Marco Poletti <poletti.marco@gmail.com>
-COPY ubuntu_arm-18.04_custom.list /etc/apt/sources.list.d/
-COPY common_install.sh common_cleanup.sh ubuntu_arm-18.04_install.sh /
+COPY common_install.sh common_cleanup.sh /
-RUN bash -x /common_install.sh && \
- bash -x /ubuntu_arm-18.04_install.sh && \
- bash -x /common_cleanup.sh
+RUN bash -x /common_install.sh
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-8 \
+ g++-7 \
+ g++-5 \
+ clang-3.9 \
+ clang-4.0 \
+ clang-5.0 \
+ clang-6.0 \
+ python \
+ python3-sh \
+ python3-typed-ast \
+ clang-tidy \
+ clang-format
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/Dockerfile.ubuntu_arm-20.04 b/extras/dockerfiles/Dockerfile.ubuntu_arm-20.04
new file mode 100644
index 0000000..6d84554
--- /dev/null
+++ b/extras/dockerfiles/Dockerfile.ubuntu_arm-20.04
@@ -0,0 +1,22 @@
+FROM multiarch/ubuntu-core:arm64-focal
+MAINTAINER Marco Poletti <poletti.marco@gmail.com>
+
+COPY common_install.sh common_cleanup.sh /
+
+RUN bash -x /common_install.sh
+RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ g++-7 \
+ g++-8 \
+ g++-9 \
+ g++-10 \
+ clang-6.0 \
+ clang-7 \
+ clang-8 \
+ clang-9 \
+ clang-10 \
+ python \
+ python3-sh \
+ python3-typed-ast \
+ clang-tidy \
+ clang-format
+RUN bash -x /common_cleanup.sh
diff --git a/extras/dockerfiles/common_install.sh b/extras/dockerfiles/common_install.sh
index ba63b2c..7eff017 100644
--- a/extras/dockerfiles/common_install.sh
+++ b/extras/dockerfiles/common_install.sh
@@ -3,7 +3,7 @@
set -e
apt-get update -qq
-apt-get install -y --no-install-recommends wget gnupg
+apt-get install -y --no-install-recommends wget gnupg ca-certificates apt-transport-https
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add -
@@ -24,15 +24,7 @@ apt-get install -y --allow-unauthenticated --no-install-recommends \
libc++-dev \
libc++abi1 \
libc++abi-dev \
- python3-pip \
- python3-setuptools \
- python3-networkx \
- dirmngr
-
-pip3 install --upgrade pip
-python3 -m pip install absl-py
-python3 -m pip install bidict
-python3 -m pip install pytest
-python3 -m pip install pytest-xdist
-python3 -m pip install sh
-python3 -m pip install wheel
+ dirmngr \
+ python \
+ python3 \
+ python3-setuptools
diff --git a/extras/dockerfiles/rebuild_all.sh b/extras/dockerfiles/rebuild_all.sh
index 545df07..f0e23d2 100755
--- a/extras/dockerfiles/rebuild_all.sh
+++ b/extras/dockerfiles/rebuild_all.sh
@@ -7,15 +7,15 @@ docker run --rm --privileged multiarch/qemu-user-static:register --reset
COMMANDS=()
-for V in 16.04 17.04 18.04 18.10 19.04 16.04
+for V in 18.04 19.10 20.04 20.10
do
- C="docker build -t polettimarco/fruit-basesystem:ubuntu-$V -f Dockerfile.ubuntu-$V ."
+ C="docker build --squash -t polettimarco/fruit-basesystem:ubuntu-$V -f Dockerfile.ubuntu-$V ."
COMMANDS+=("$C || { echo; echo FAILED: '$C'; echo; exit 1; }")
done
-for V in 16.04 18.04
+for V in 18.04 20.04
do
- C="docker build -t polettimarco/fruit-basesystem:ubuntu_arm-$V -f Dockerfile.ubuntu_arm-$V ."
+ C="docker build --squash -t polettimarco/fruit-basesystem:ubuntu_arm-$V -f Dockerfile.ubuntu_arm-$V ."
COMMANDS+=("$C || { echo; echo FAILED: '$C'; echo; exit 1; }")
done
@@ -28,10 +28,7 @@ done | xargs -P 0 -L 1 -d '\n' bash -c || {
# This way we get better diagnostics.
for C in "${COMMANDS[@]}"
do
- $C || {
- echo "Failed: $C"
- exit 1
- }
+ bash -c "$C" || exit 1
done
}
diff --git a/extras/dockerfiles/ubuntu-16.04_custom.list b/extras/dockerfiles/ubuntu-16.04_custom.list
deleted file mode 100644
index 54c95ff..0000000
--- a/extras/dockerfiles/ubuntu-16.04_custom.list
+++ /dev/null
@@ -1,11 +0,0 @@
-deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main
-deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main
-deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial main
-deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial main
-deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main
-deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main
-deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main
-deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main
-deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main
-deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main
-deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8
diff --git a/extras/dockerfiles/ubuntu-16.04_install.sh b/extras/dockerfiles/ubuntu-16.04_install.sh
deleted file mode 100644
index 4d47e56..0000000
--- a/extras/dockerfiles/ubuntu-16.04_install.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --no-install-recommends \
- curl
-
-# For the Bazel repository
-curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- clang-3.5 \
- clang-3.6 \
- clang-3.7 \
- clang-3.8 \
- clang-3.9 \
- clang-4.0 \
- g++-5 \
- g++-4.9 \
- g++-6 \
- python \
- bazel \
- git \
- openjdk-8-jdk \
- clang-format
-
-pip3 install typed_ast
diff --git a/extras/dockerfiles/ubuntu-17.04_custom.list b/extras/dockerfiles/ubuntu-17.04_custom.list
deleted file mode 100644
index dfafeb4..0000000
--- a/extras/dockerfiles/ubuntu-17.04_custom.list
+++ /dev/null
@@ -1,8 +0,0 @@
-deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu zesty main
-deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu zesty main
-deb http://apt.llvm.org/zesty/ llvm-toolchain-zesty main
-deb-src http://apt.llvm.org/zesty/ llvm-toolchain-zesty main
-deb http://apt.llvm.org/zesty/ llvm-toolchain-zesty-3.9 main
-deb-src http://apt.llvm.org/zesty/ llvm-toolchain-zesty-3.9 main
-deb http://apt.llvm.org/zesty/ llvm-toolchain-zesty-4.0 main
-deb-src http://apt.llvm.org/zesty/ llvm-toolchain-zesty-4.0 main
diff --git a/extras/dockerfiles/ubuntu-17.04_install.sh b/extras/dockerfiles/ubuntu-17.04_install.sh
deleted file mode 100644
index 6c774ef..0000000
--- a/extras/dockerfiles/ubuntu-17.04_install.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1E9377A2BA9EF27F
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- clang-3.7 \
- clang-3.8 \
- clang-3.9 \
- clang-4.0 \
- g++-5 \
- g++-4.9 \
- g++-6 \
- python \
- clang-format
-
-pip3 install typed_ast
diff --git a/extras/dockerfiles/ubuntu-18.04_custom.list b/extras/dockerfiles/ubuntu-18.04_custom.list
index e69de29..171b878 100644
--- a/extras/dockerfiles/ubuntu-18.04_custom.list
+++ b/extras/dockerfiles/ubuntu-18.04_custom.list
@@ -0,0 +1,17 @@
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main
+deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main
+deb-src http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main
+
+deb http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main
+deb-src http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic main
diff --git a/extras/dockerfiles/ubuntu-18.04_install.sh b/extras/dockerfiles/ubuntu-18.04_install.sh
deleted file mode 100644
index 3d4cde7..0000000
--- a/extras/dockerfiles/ubuntu-18.04_install.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --no-install-recommends \
- curl
-
-# For the Bazel repository
-curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
-
-echo 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8' >> /etc/apt/sources.list.d/bazel.list
-
-apt-get update -qq
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- g++-8 \
- g++-7 \
- g++-5 \
- clang-3.9 \
- clang-4.0 \
- clang-5.0 \
- clang-6.0 \
- bazel \
- git \
- python \
- python3-sh \
- python3-typed-ast \
- clang-format
diff --git a/extras/dockerfiles/ubuntu-18.10_custom.list b/extras/dockerfiles/ubuntu-18.10_custom.list
deleted file mode 100644
index e69de29..0000000
--- a/extras/dockerfiles/ubuntu-18.10_custom.list
+++ /dev/null
diff --git a/extras/dockerfiles/ubuntu-18.10_install.sh b/extras/dockerfiles/ubuntu-18.10_install.sh
deleted file mode 100644
index 1357b11..0000000
--- a/extras/dockerfiles/ubuntu-18.10_install.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- g++-7 \
- g++-8 \
- g++-5 \
- clang-3.9 \
- clang-4.0 \
- clang-6.0 \
- clang-7 \
- python \
- python3-sh \
- python3-typed-ast \
- clang-format
diff --git a/extras/dockerfiles/ubuntu-19.04_custom.list b/extras/dockerfiles/ubuntu-19.04_custom.list
deleted file mode 100644
index e69de29..0000000
--- a/extras/dockerfiles/ubuntu-19.04_custom.list
+++ /dev/null
diff --git a/extras/dockerfiles/ubuntu-19.04_install.sh b/extras/dockerfiles/ubuntu-19.04_install.sh
deleted file mode 100644
index 2f78bdd..0000000
--- a/extras/dockerfiles/ubuntu-19.04_install.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- g++-7 \
- g++-8 \
- g++-9 \
- clang-6.0 \
- clang-7 \
- clang-8 \
- python \
- python3-sh \
- python3-typed-ast \
- clang-format
diff --git a/extras/dockerfiles/ubuntu-19.10_custom.list b/extras/dockerfiles/ubuntu-19.10_custom.list
new file mode 100644
index 0000000..ac1b4bd
--- /dev/null
+++ b/extras/dockerfiles/ubuntu-19.10_custom.list
@@ -0,0 +1,6 @@
+deb http://apt.llvm.org/eoan/ llvm-toolchain-eoan main
+deb-src http://apt.llvm.org/eoan/ llvm-toolchain-eoan main
+deb http://apt.llvm.org/eoan/ llvm-toolchain-eoan-9 main
+deb-src http://apt.llvm.org/eoan/ llvm-toolchain-eoan-9 main
+deb http://apt.llvm.org/eoan/ llvm-toolchain-eoan-10 main
+deb-src http://apt.llvm.org/eoan/ llvm-toolchain-eoan-10 main
diff --git a/extras/dockerfiles/ubuntu-20.04_custom.list b/extras/dockerfiles/ubuntu-20.04_custom.list
new file mode 100644
index 0000000..c26e2d9
--- /dev/null
+++ b/extras/dockerfiles/ubuntu-20.04_custom.list
@@ -0,0 +1,4 @@
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
diff --git a/extras/dockerfiles/ubuntu-20.10_custom.list b/extras/dockerfiles/ubuntu-20.10_custom.list
new file mode 100644
index 0000000..c26e2d9
--- /dev/null
+++ b/extras/dockerfiles/ubuntu-20.10_custom.list
@@ -0,0 +1,4 @@
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main
diff --git a/extras/dockerfiles/ubuntu_arm-16.04_install.sh b/extras/dockerfiles/ubuntu_arm-16.04_install.sh
deleted file mode 100644
index 504b2c0..0000000
--- a/extras/dockerfiles/ubuntu_arm-16.04_install.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- clang-3.5 \
- clang-3.6 \
- clang-3.7 \
- clang-3.9 \
- clang-4.0 \
- g++-5 \
- g++-4.9 \
- g++-6 \
- python \
- clang-format
diff --git a/extras/dockerfiles/ubuntu_arm-18.04_custom.list b/extras/dockerfiles/ubuntu_arm-18.04_custom.list
deleted file mode 100644
index e347ae1..0000000
--- a/extras/dockerfiles/ubuntu_arm-18.04_custom.list
+++ /dev/null
@@ -1,8 +0,0 @@
-#deb [trusted=yes] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main
-#deb-src [trusted=yes] http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main
-#deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
-#deb-src [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic main
-#deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-4.0 main
-#deb-src [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-4.0 main
-#deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main
-#deb-src [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-5.0 main
diff --git a/extras/dockerfiles/ubuntu_arm-18.04_install.sh b/extras/dockerfiles/ubuntu_arm-18.04_install.sh
deleted file mode 100644
index 8e21982..0000000
--- a/extras/dockerfiles/ubuntu_arm-18.04_install.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-set -e
-
-apt-get install -y --allow-unauthenticated --no-install-recommends \
- g++-8 \
- g++-7 \
- g++-5 \
- clang-3.9 \
- clang-4.0 \
- clang-5.0 \
- clang-6.0 \
- python \
- python3-sh \
- python3-typed-ast \
- clang-format
diff --git a/extras/packaging/CMakeLists.txt b/extras/packaging/CMakeLists.txt
index 7592bf0..09eb4d0 100644
--- a/extras/packaging/CMakeLists.txt
+++ b/extras/packaging/CMakeLists.txt
@@ -8,7 +8,7 @@ libfruit.install
libfruit.spec
)
-# This places configured files (build files with @FRUIT_VERSION@ replaced) in build/extras/packaging/built
+# This places configured files (build files with @Fruit_VERSION@ replaced) in build/extras/packaging/built
foreach(F ${PACKAGING_FILES})
configure_file(${F} built/${F} @ONLY)
@@ -16,9 +16,9 @@ endforeach(F)
configure_file(PKGBUILD PKGBUILD-template @ONLY)
-add_custom_target(fruit-${FRUIT_VERSION}.tar.gz ALL
+add_custom_target(fruit-${Fruit_VERSION}.tar.gz ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/PKGBUILD-template
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..
- COMMAND git archive -o ${CMAKE_CURRENT_BINARY_DIR}/built/fruit-${FRUIT_VERSION}.tar.gz --prefix=fruit-${FRUIT_VERSION}/ HEAD
- COMMAND md5sum ${CMAKE_CURRENT_BINARY_DIR}/built/fruit-${FRUIT_VERSION}.tar.gz | awk '{print $$1}' >${CMAKE_CURRENT_BINARY_DIR}/tarball-md5
+ COMMAND git archive -o ${CMAKE_CURRENT_BINARY_DIR}/built/fruit-${Fruit_VERSION}.tar.gz --prefix=fruit-${Fruit_VERSION}/ HEAD
+ COMMAND md5sum ${CMAKE_CURRENT_BINARY_DIR}/built/fruit-${Fruit_VERSION}.tar.gz | awk '{print $$1}' >${CMAKE_CURRENT_BINARY_DIR}/tarball-md5
COMMAND sed "\"s/.*md5sums.*/md5sums=(`cat" "${CMAKE_CURRENT_BINARY_DIR}/tarball-md5`)/\"" <${CMAKE_CURRENT_BINARY_DIR}/PKGBUILD-template >${CMAKE_CURRENT_BINARY_DIR}/built/PKGBUILD)
diff --git a/extras/packaging/PKGBUILD b/extras/packaging/PKGBUILD
index b7b06cc..6f68971 100644
--- a/extras/packaging/PKGBUILD
+++ b/extras/packaging/PKGBUILD
@@ -1,6 +1,6 @@
# Maintainer: Marco Poletti <poletti.marco@gmail.com>
pkgname=libfruit
-pkgver=@FRUIT_VERSION@
+pkgver=@Fruit_VERSION@
pkgrel=0
pkgdesc="Fruit is a dependency injection framework for C++."
url="https://github.com/google/fruit"
diff --git a/extras/packaging/deploy_to_bintray.bat b/extras/packaging/deploy_to_bintray.bat
index 2473343..1a28914 100644
--- a/extras/packaging/deploy_to_bintray.bat
+++ b/extras/packaging/deploy_to_bintray.bat
@@ -1,4 +1,4 @@
-set FRUIT_VERSION=3.4.0
+set FRUIT_VERSION=354.0
for %%G in (Release Debug) DO CMD /C for %%H in (True False) DO CMD /C for %%I in (True False) DO conan create . google/stable -o fruit:shared=%%H -o fruit:use_boost=%%I -s build_type=%%G
diff --git a/extras/packaging/deploy_to_bintray.sh b/extras/packaging/deploy_to_bintray.sh
index 31a80c7..78d5c51 100755
--- a/extras/packaging/deploy_to_bintray.sh
+++ b/extras/packaging/deploy_to_bintray.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-FRUIT_VERSION=3.4.0
+FRUIT_VERSION=3.6.0
# To authenticate:
# conan user -p <BINTRAY_API_KEY_HERE> -r fruit-bintray polettimarco
diff --git a/extras/packaging/libfruit.dsc b/extras/packaging/libfruit.dsc
index 07bd92e..8b58a26 100644
--- a/extras/packaging/libfruit.dsc
+++ b/extras/packaging/libfruit.dsc
@@ -1,10 +1,10 @@
Format: 1.0
Source: libfruit
-Version: @FRUIT_VERSION@-0
+Version: @Fruit_VERSION@-0
Binary: libfruit
Maintainer: Marco Poletti <poletti.marco@gmail.com>
Architecture: any
Build-Depends: debhelper (>= 4.1.16), cmake, libboost-dev, gcc (>= 4:5.0.0)
Files:
- d57283ebb8157ae919762c58419353c8 133282 libfruit_@FRUIT_VERSION@.orig.tar.gz
- 2fecf324a32123b08cefc0f047bca5ee 63176 libfruit_@FRUIT_VERSION@-0.diff.tar.gz \ No newline at end of file
+ d57283ebb8157ae919762c58419353c8 133282 libfruit_@Fruit_VERSION@.orig.tar.gz
+ 2fecf324a32123b08cefc0f047bca5ee 63176 libfruit_@Fruit_VERSION@-0.diff.tar.gz
diff --git a/extras/packaging/libfruit.spec b/extras/packaging/libfruit.spec
index 378abe5..dc63192 100644
--- a/extras/packaging/libfruit.spec
+++ b/extras/packaging/libfruit.spec
@@ -3,7 +3,7 @@
#
Name: libfruit
-Version: @FRUIT_VERSION@
+Version: @Fruit_VERSION@
Release: 0
Summary: Dependency Injection Framework For C++
License: Apache-2.0
@@ -47,8 +47,8 @@ most injection problems at compile-time.
%setup -q -n fruit-%{version}
%build
-cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DINSTALL_LIBRARY_DIR=%{_libdir} -DCMAKE_BUILD_TYPE=RelWithDebInfo
-
+cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DCMAKE_INSTALL_LIBDIR=%{_libdir} -DCMAKE_BUILD_TYPE=RelWithDebInfo
+
%{__make} %{?jobs:-j%jobs}
%install
diff --git a/extras/scripts/postsubmit-helper.sh b/extras/scripts/postsubmit-helper.sh
index 36169bb..eecd3c0 100755
--- a/extras/scripts/postsubmit-helper.sh
+++ b/extras/scripts/postsubmit-helper.sh
@@ -37,6 +37,11 @@ gcc-9)
export CXX=g++-9
;;
+gcc-10)
+ export CC=gcc-10
+ export CXX=g++-10
+ ;;
+
clang-3.5)
export CC=clang-3.5
export CXX=clang++-3.5
@@ -87,6 +92,21 @@ clang-8.0)
export CXX=clang++-8
;;
+clang-9.0)
+ export CC=clang-9
+ export CXX=clang++-9
+ ;;
+
+clang-10.0)
+ export CC=clang-10
+ export CXX=clang++-10
+ ;;
+
+clang-11.0)
+ export CC=clang-11
+ export CXX=clang++-11
+ ;;
+
clang-default)
export CC=clang
export CXX=clang++
@@ -107,28 +127,44 @@ run_make() {
if [[ "${COMPILER}" != "bazel" ]]
then
# This is only needed in OS X but it has no effect on Linux so we can add it unconditionally.
- BOOST_INCLUDE_FLAG="-I /usr/local/include/boost"
- COMMON_CXX_FLAGS="$STLARG $BOOST_INCLUDE_FLAG -Werror -pedantic"
+ BOOST_INCLUDE_FLAG="-I /usr/local/include/boost -I /usr/local/include"
+ # -Wdtor-name (part of -pedantic) is *very* pedantic. Following that results in weird-looking code.
+ # See https://bugs.llvm.org/show_bug.cgi?id=46979.
+ COMMON_CXX_FLAGS="$STLARG $BOOST_INCLUDE_FLAG -Werror -pedantic -Wno-unknown-warning-option -Wno-dtor-name -Winvalid-pch"
echo CXX version: $($CXX --version)
echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)
echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1))
case "$1" in
- DebugPlain) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2") ;;
- DebugPlainNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
- DebugAsan) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address") ;;
- DebugAsanNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
- DebugAsanUbsan) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined") ;;
- DebugAsanUbsanNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
- DebugValgrind) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
- DebugValgrindNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
- ReleasePlain) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS") ;;
- ReleasePlainNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
- ReleaseValgrind) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
- ReleaseValgrindNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugPlain) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2") ;;
+ DebugPlainNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2") ;;
+ DebugPlainNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugPlainNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugAsan) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address") ;;
+ DebugAsanNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address") ;;
+ DebugAsanNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugAsanNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugAsanUbsan) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined") ;;
+ DebugAsanUbsanNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined") ;;
+ DebugAsanUbsanNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugAsanUbsanNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O0 -fsanitize=address,undefined" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugValgrind) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
+ DebugValgrindNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
+ DebugValgrindNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ DebugValgrindNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1 -O2" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ ReleasePlain) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS") ;;
+ ReleasePlainNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS") ;;
+ ReleasePlainNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ ReleasePlainNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ ReleaseValgrind) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
+ ReleaseValgrindNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE) ;;
+ ReleaseValgrindNoPch) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
+ ReleaseValgrindNoPchNoClangTidy) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DFRUIT_ENABLE_CLANG_TIDY=FALSE -DCMAKE_CXX_FLAGS="$COMMON_CXX_FLAGS" -DRUN_TESTS_UNDER_VALGRIND=TRUE -DFRUIT_TESTS_USE_PRECOMPILED_HEADERS=OFF) ;;
*) echo "Error: you need to specify one of the supported postsubmit modes (see postsubmit.sh)."; exit 1 ;;
esac
+ # Setting compilers only via env vars doesn't work when using recent versions of XCode.
+ CMAKE_ARGS+=(-DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX)
SOURCES_PATH="$PWD"
@@ -165,8 +201,12 @@ then
make install
else
# COMPILER=bazel
-
- BAZEL_FLAGS=("--python_path=$(which python3)")
+
+ # In recent versions of Bazel (as of May 2020), --python_path is ignored unless
+ # --noincompatible_use_python_toolchains is also used.
+ # Ignoring --python_path is ok in Ubuntu 20.04 since 3.8 is the default Python there, but causes problems in docker
+ # images with older Ubuntu versions that have both 3.8 and another 3.x version installed.
+ BAZEL_FLAGS=("--python_path=$(which python3.8)" "--noincompatible_use_python_toolchains")
case "$1" in
DebugPlain) ;;
ReleasePlain) BAZEL_FLAGS+=("-c" "opt") ;;
diff --git a/extras/scripts/postsubmit.bat b/extras/scripts/postsubmit.bat
index 59fbb4c..c23dd79 100644
--- a/extras/scripts/postsubmit.bat
+++ b/extras/scripts/postsubmit.bat
@@ -42,6 +42,7 @@ IF "%CMAKE_GENERATOR%"=="MinGW Makefiles" (
msbuild ALL_BUILD.vcxproj || exit /b 1
)
+pip3 install absl-py
pip3 install pytest
pip3 install pytest-xdist
diff --git a/extras/scripts/travis_ci_install_osx.sh b/extras/scripts/travis_ci_install_osx.sh
index 0bef2b1..d3cc7c8 100755
--- a/extras/scripts/travis_ci_install_osx.sh
+++ b/extras/scripts/travis_ci_install_osx.sh
@@ -2,8 +2,17 @@
set -e
+# These packages depend on the ones that we update but we don't care about these, we don't want to waste time upgrading
+# them.
+for p in postgis ansible libdap libspatialite gdal mercurial poppler
+do
+ brew pin $p
+done
+
install_brew_package() {
- time (brew install "$@" || brew outdated "$1" || brew upgrade "$@")
+ time (brew install "$@" || brew outdated "$1" || brew upgrade "$@" || true)
+ # Some formulas are not linked into /usr/local by default, make sure they are.
+ time (brew link --force --overwrite "$@" || true)
}
# For md5sum, timeout
@@ -24,15 +33,29 @@ gcc-7) install_brew_package gcc@7 ;;
gcc-8) install_brew_package gcc@8 ;;
gcc-9) install_brew_package gcc@9 ;;
clang-default) ;;
-clang-3.9) install_brew_package llvm@3.9 ;;
-clang-4.0) install_brew_package llvm@4 ;;
-clang-5.0) install_brew_package llvm@5 ;;
-clang-6.0) install_brew_package llvm@6 ;;
-clang-7.0) install_brew_package llvm@7 ;;
-clang-8.0) install_brew_package llvm@8 ;;
+clang-6.0)
+ install_brew_package llvm@6
+ ln -s /usr/local/opt/llvm@6/bin/clang++ /usr/local/bin/clang++-6.0
+ ;;
+clang-7.0)
+ install_brew_package llvm@7
+ ln -s /usr/local/opt/llvm@7/bin/clang++ /usr/local/bin/clang++-7
+ ;;
+clang-8.0)
+ install_brew_package llvm@8
+ ln -s /usr/local/opt/llvm@8/bin/clang++ /usr/local/bin/clang++-8
+ ;;
+clang-9.0)
+ install_brew_package llvm@9
+ ln -s /usr/local/opt/llvm@9/bin/clang++ /usr/local/bin/clang++-9
+ ln -s /usr/local/opt/llvm@9/bin/clang /usr/local/bin/clang-9
+ ;;
*) echo "Compiler not supported: ${COMPILER}. See travis_ci_install_osx.sh"; exit 1 ;;
esac
+# So that we can "brew link" python@3 instead.
+brew unlink python@2
+
install_brew_package boost
install_brew_package python
time pip3 install absl-py
diff --git a/extras/scripts/travis_yml_generator.py b/extras/scripts/travis_yml_generator.py
index e2f5581..46c5a92 100755
--- a/extras/scripts/travis_yml_generator.py
+++ b/extras/scripts/travis_yml_generator.py
@@ -29,7 +29,7 @@ def determine_compiler_kind(compiler):
raise Exception('Unexpected compiler: %s' % compiler)
-def determine_tests(asan, ubsan, smoke_tests, use_precompiled_headers_in_tests, exclude_tests,
+def determine_tests(asan, ubsan, clang_tidy, smoke_tests, use_precompiled_headers_in_tests, exclude_tests,
include_only_tests):
tests = []
has_debug_build = False
@@ -51,7 +51,7 @@ def determine_tests(asan, ubsan, smoke_tests, use_precompiled_headers_in_tests,
if excessive_excluded_tests:
raise Exception(
'Some tests were excluded but were not going to run anyway: %s. '
- 'Tests to run (ignoring the possible NoPch prefix): %s'
+ 'Tests to run (ignoring the possible NoPch/NoClangTidy prefixes): %s'
% (excessive_excluded_tests, tests))
if include_only_tests is not None:
if exclude_tests != []:
@@ -61,6 +61,8 @@ def determine_tests(asan, ubsan, smoke_tests, use_precompiled_headers_in_tests,
tests = [test for test in tests if test not in exclude_tests]
if not use_precompiled_headers_in_tests:
tests = [test + 'NoPch' for test in tests]
+ if not clang_tidy:
+ tests = [test + 'NoClangTidy' for test in tests]
return tests
@@ -72,7 +74,7 @@ def generate_env_string_for_env(env):
return ' '.join(['%s=%s' % (var_name, value) for (var_name, value) in sorted(env.items())])
-def add_ubuntu_tests(ubuntu_version, compiler, os='linux', stl=None, asan=True, ubsan=True,
+def add_ubuntu_tests(ubuntu_version, compiler, os='linux', stl=None, asan=True, ubsan=True, clang_tidy=True,
use_precompiled_headers_in_tests=True, smoke_tests=[], exclude_tests=[], include_only_tests=None):
env = {
'UBUNTU': ubuntu_version,
@@ -84,7 +86,7 @@ def add_ubuntu_tests(ubuntu_version, compiler, os='linux', stl=None, asan=True,
export_statements = 'export OS=' + os + '; ' + generate_export_statements_for_env(env=env)
test_environment_template = {'os': 'linux', 'compiler': compiler_kind,
'install': '%s extras/scripts/travis_ci_install_linux.sh' % export_statements}
- tests = determine_tests(asan, ubsan, smoke_tests,
+ tests = determine_tests(asan, ubsan, clang_tidy, smoke_tests,
use_precompiled_headers_in_tests=use_precompiled_headers_in_tests,
exclude_tests=exclude_tests,
include_only_tests=include_only_tests)
@@ -99,7 +101,7 @@ def add_ubuntu_tests(ubuntu_version, compiler, os='linux', stl=None, asan=True,
build_matrix_rows.append(test_environment)
-def add_osx_tests(compiler, xcode_version=None, stl=None, asan=True, ubsan=True,
+def add_osx_tests(compiler, xcode_version=None, stl=None, asan=True, ubsan=True, clang_tidy=True,
use_precompiled_headers_in_tests=True, smoke_tests=[], exclude_tests=[], include_only_tests=None):
env = {'COMPILER': compiler}
if stl is not None:
@@ -107,11 +109,11 @@ def add_osx_tests(compiler, xcode_version=None, stl=None, asan=True, ubsan=True,
compiler_kind = determine_compiler_kind(compiler)
export_statements = 'export OS=osx; ' + generate_export_statements_for_env(env=env)
test_environment_template = {'os': 'osx', 'compiler': compiler_kind,
- 'install': '%s extras/scripts/travis_ci_install_osx.sh' % export_statements}
+ 'install': '%s travis_wait extras/scripts/travis_ci_install_osx.sh' % export_statements}
if xcode_version is not None:
test_environment_template['osx_image'] = 'xcode%s' % xcode_version
- tests = determine_tests(asan, ubsan, smoke_tests,
+ tests = determine_tests(asan, ubsan, clang_tidy, smoke_tests,
use_precompiled_headers_in_tests=use_precompiled_headers_in_tests,
exclude_tests=exclude_tests, include_only_tests=include_only_tests)
for test in tests:
@@ -142,27 +144,26 @@ def add_bazel_tests(ubuntu_version, smoke_tests=[]):
else:
build_matrix_rows.append(test_environment)
-
-# TODO: re-enable ASan/UBSan once they work in Travis CI. ATM (as of 18 November 2017) they fail due to https://github.com/google/sanitizers/issues/837
-add_ubuntu_tests(ubuntu_version='19.04', compiler='gcc-9', asan=False, ubsan=False,
+add_ubuntu_tests(ubuntu_version='20.10', compiler='gcc-7')
+add_ubuntu_tests(ubuntu_version='20.10', compiler='gcc-10',
smoke_tests=['DebugPlain', 'ReleasePlain'])
-add_ubuntu_tests(ubuntu_version='19.04', compiler='clang-6.0', stl='libstdc++',
+add_ubuntu_tests(ubuntu_version='20.10', compiler='clang-8.0', stl='libstdc++',
smoke_tests=['DebugPlain', 'DebugAsanUbsan', 'ReleasePlain'])
-add_ubuntu_tests(ubuntu_version='19.04', compiler='clang-8.0', stl='libstdc++',
- # Disabled due to https://bugs.llvm.org/show_bug.cgi?id=41625.
- use_precompiled_headers_in_tests=False)
-add_ubuntu_tests(ubuntu_version='19.04', compiler='clang-8.0', stl='libc++',
- # Disabled due to https://bugs.llvm.org/show_bug.cgi?id=41625.
- use_precompiled_headers_in_tests=False)
+add_ubuntu_tests(ubuntu_version='20.10', compiler='clang-11.0', stl='libstdc++')
+add_ubuntu_tests(ubuntu_version='20.10', compiler='clang-11.0', stl='libc++')
-add_ubuntu_tests(ubuntu_version='18.10', compiler='gcc-8', asan=False, ubsan=False)
-add_ubuntu_tests(ubuntu_version='18.10', compiler='clang-4.0', stl='libstdc++')
-add_ubuntu_tests(ubuntu_version='18.10', compiler='clang-7.0', stl='libstdc++',
+add_ubuntu_tests(ubuntu_version='20.04', compiler='gcc-7')
+add_ubuntu_tests(ubuntu_version='20.04', compiler='clang-6.0', stl='libstdc++',
+ smoke_tests=['DebugPlain', 'DebugAsanUbsan', 'ReleasePlain'])
+
+add_ubuntu_tests(ubuntu_version='18.04', compiler='gcc-5', asan=False, ubsan=False)
+add_ubuntu_tests(ubuntu_version='18.04', compiler='gcc-8', asan=False, ubsan=False)
+add_ubuntu_tests(ubuntu_version='18.04', compiler='clang-3.9', stl='libstdc++')
+add_ubuntu_tests(ubuntu_version='18.04', compiler='clang-7.0', stl='libstdc++',
# Disabled due to https://bugs.llvm.org/show_bug.cgi?id=41625.
use_precompiled_headers_in_tests=False)
add_bazel_tests(ubuntu_version='18.04', smoke_tests=['DebugPlain'])
-add_bazel_tests(ubuntu_version='16.04')
# ASan/UBSan are disabled for all these, the analysis on later versions is better anyway.
# Also, in some combinations they wouldn't work.
@@ -175,19 +176,23 @@ add_ubuntu_tests(ubuntu_version='16.04', compiler='clang-3.9', stl='libstdc++',
# overridden at runtime. This was likely caused by different translation units being compiled with different
# visibility settings.
# and the build eventually fails or times out.
-add_osx_tests(compiler='gcc-6', xcode_version='11.4', asan=False, ubsan=False)
-add_osx_tests(compiler='gcc-9', xcode_version='11.4', asan=False, ubsan=False, smoke_tests=['DebugPlain'])
-add_osx_tests(compiler='clang-4.0', xcode_version='11.4', stl='libc++')
+add_osx_tests(compiler='gcc-6', xcode_version='11.4', asan=False, ubsan=False, clang_tidy=False)
+add_osx_tests(compiler='gcc-9', xcode_version='11.4', asan=False, ubsan=False, clang_tidy=False, smoke_tests=['DebugPlain'],
+ # Using PCHs fails with this error:
+ # error: /Users/travis/build/google/fruit/build/tests/test_common-precompiled.h.gch: had text segment
+ # at different address
+ use_precompiled_headers_in_tests=False)
+add_osx_tests(compiler='clang-6.0', xcode_version='11.4', stl='libc++', clang_tidy=False)
add_osx_tests(compiler='clang-8.0', xcode_version='11.4', stl='libc++', smoke_tests=['DebugPlain'],
+ clang_tidy=False,
# Disabled due to https://bugs.llvm.org/show_bug.cgi?id=41625.
use_precompiled_headers_in_tests=False)
-# UBSan is disabled because AppleClang does not support -fsanitize=undefined.
-add_osx_tests(compiler='clang-default', xcode_version='8.3', stl='libc++', ubsan=False)
-
-add_osx_tests(compiler='clang-default', xcode_version='9.4', stl='libc++')
-add_osx_tests(compiler='clang-default', xcode_version='10.3', stl='libc++', smoke_tests=['DebugPlain'])
-add_osx_tests(compiler='clang-default', xcode_version='11.4', stl='libc++', smoke_tests=['DebugPlain'])
+add_osx_tests(compiler='clang-default', xcode_version='9.4', stl='libc++', clang_tidy=False)
+add_osx_tests(compiler='clang-default', xcode_version='11.3', stl='libc++', clang_tidy=False,
+ # Disabled due to https://bugs.llvm.org/show_bug.cgi?id=41625.
+ use_precompiled_headers_in_tests=False,
+ smoke_tests=['DebugPlain'])
# ** Disabled combinations **
#
@@ -222,7 +227,7 @@ add_osx_tests(compiler='clang-default', xcode_version='11.4', stl='libc++', smok
yaml_file = {
'sudo': 'required',
- 'dist': 'trusty',
+ 'dist': 'xenial',
'services': ['docker'],
'language': 'cpp',
'branches': {
diff --git a/include/fruit/component.h b/include/fruit/component.h
index 98eb727..cd8be1f 100644
--- a/include/fruit/component.h
+++ b/include/fruit/component.h
@@ -44,7 +44,7 @@ namespace fruit {
template <typename... Params>
class Component {
public:
- Component(Component&&) = default;
+ Component(Component&&) noexcept = default;
Component& operator=(Component&&) = delete;
Component& operator=(const Component&) = delete;
@@ -55,7 +55,7 @@ public:
* This is usually called implicitly when returning a component from a function. See PartialComponent for an example.
*/
template <typename... Bindings>
- Component(PartialComponent<Bindings...>&& component);
+ Component(PartialComponent<Bindings...>&& component) noexcept; // NOLINT(google-explicit-constructor)
private:
// Do not use. Use fruit::createComponent() instead.
@@ -938,7 +938,8 @@ public:
Bindings...>
with(ReplacedComponent (*)(FormalArgs...), Args&&... args);
- PartialComponentWithReplacementInProgress(storage_t storage) : storage(storage) {}
+ PartialComponentWithReplacementInProgress(storage_t storage) // NOLINT(google-explicit-constructor)
+ : storage(storage) {}
private:
storage_t storage;
@@ -1048,7 +1049,14 @@ public:
fruit::Component<OtherComponentParams...>, FormalArgs...>
replace(fruit::Component<OtherComponentParams...> (*)(FormalArgs...), Args&&... args);
- ~PartialComponent();
+ ~PartialComponent() = default;
+
+ // Do not use. Use fruit::createComponent() instead.
+ PartialComponent() = delete;
+
+ // Do not use. Only use PartialComponent for temporaries, and then convert it to a Component.
+ PartialComponent(const PartialComponent&) = delete;
+ PartialComponent(PartialComponent&&) = delete;
private:
template <typename... OtherBindings>
@@ -1059,14 +1067,7 @@ private:
fruit::impl::PartialComponentStorage<Bindings...> storage;
- // Do not use. Use fruit::createComponent() instead.
- PartialComponent() = delete;
-
- // Do not use. Only use PartialComponent for temporaries, and then convert it to a Component.
- PartialComponent(const PartialComponent&) = delete;
- PartialComponent(PartialComponent&&) = delete;
-
- PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage);
+ PartialComponent(fruit::impl::PartialComponentStorage<Bindings...> storage); // NOLINT(google-explicit-constructor)
template <typename NewBinding>
using OpFor = typename fruit::impl::meta::OpForComponent<Bindings...>::template AddBinding<NewBinding>;
diff --git a/include/fruit/component_function.h b/include/fruit/component_function.h
index 56b77a1..70299ed 100644
--- a/include/fruit/component_function.h
+++ b/include/fruit/component_function.h
@@ -34,7 +34,7 @@ private:
/**
* This is (intentionally) private, use fruit::componentFunction() to construct ComponentFunction objects.
*/
- ComponentFunction(ComponentType (*getComponent)(ComponentFunctionArgs...), ComponentFunctionArgs... args);
+ explicit ComponentFunction(ComponentType (*getComponent)(ComponentFunctionArgs...), ComponentFunctionArgs... args);
friend struct fruit::impl::ComponentStorageEntry;
@@ -45,10 +45,13 @@ public:
ComponentType (*getComponent)(ComponentFunctionArgs...), ActualArgs&&... args);
ComponentFunction(const ComponentFunction&) = default;
- ComponentFunction(ComponentFunction&&) = default;
+ ComponentFunction(ComponentFunction&&) noexcept = default;
ComponentFunction& operator=(const ComponentFunction&) = default;
- ComponentFunction& operator=(ComponentFunction&&) = default;
+ ComponentFunction& operator=(ComponentFunction&& other) noexcept {
+ args_tuple = std::move(other.args_tuple);
+ return *this;
+ }
ComponentType operator()();
};
diff --git a/include/fruit/impl/component.defn.h b/include/fruit/impl/component.defn.h
index 382ecac..ddc4810 100644
--- a/include/fruit/impl/component.defn.h
+++ b/include/fruit/impl/component.defn.h
@@ -48,7 +48,7 @@ struct OpForComponent {
template <typename... Params>
template <typename... Bindings>
-inline Component<Params...>::Component(PartialComponent<Bindings...>&& partial_component) : storage() {
+inline Component<Params...>::Component(PartialComponent<Bindings...>&& partial_component) noexcept : storage() {
(void)typename fruit::impl::meta::CheckIfError<Comp>::type();
@@ -77,9 +77,6 @@ inline Component<Params...>::Component(PartialComponent<Bindings...>&& partial_c
storage = fruit::impl::ComponentStorage(std::move(entries));
}
-template <typename... Bindings>
-inline PartialComponent<Bindings...>::~PartialComponent() {}
-
inline PartialComponent<> createComponent() {
return {{}};
}
diff --git a/include/fruit/impl/component_functors.defn.h b/include/fruit/impl/component_functors.defn.h
index e03b0a8..e6778b1 100644
--- a/include/fruit/impl/component_functors.defn.h
+++ b/include/fruit/impl/component_functors.defn.h
@@ -402,7 +402,7 @@ template <int numAssistedBefore, int numNonAssistedBefore, typename Arg>
struct GetAssistedArg<numAssistedBefore, numNonAssistedBefore, Assisted<Arg>> {
template <typename InjectedArgsTuple, typename UserProvidedArgsTuple>
inline Arg operator()(InjectedArgsTuple&, UserProvidedArgsTuple& user_provided_args) {
- return std::get<numAssistedBefore>(user_provided_args);
+ return std::move(std::get<numAssistedBefore>(user_provided_args));
}
};
@@ -437,9 +437,9 @@ struct RegisterFactoryHelper {
using Result = Eval<R>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
auto function_provider = [](NakedInjectedArgs... args) {
- auto injected_args = std::make_tuple(args...);
- auto object_provider = [injected_args](NakedUserProvidedArgs... params) mutable {
- auto user_provided_args = std::tie(params...);
+ std::tuple<NakedInjectedArgs...> injected_args{args...};
+ auto object_provider = [=](NakedUserProvidedArgs... params) mutable {
+ std::tuple<NakedUserProvidedArgs...> user_provided_args{std::move(params)...};
// These are unused if they are 0-arg tuples. Silence the unused-variable warnings anyway.
(void)injected_args;
(void)user_provided_args;
@@ -570,8 +570,8 @@ struct PreProcessRegisterConstructor {
using CDeps = NormalizeTypeVector(AnnotatedArgs);
using CNonConstDeps = NormalizedNonConstTypesIn(AnnotatedArgs);
using R = AddProvidedType(Comp, AnnotatedC, Bool<true>, CDeps, CNonConstDeps);
- using type = If(
- Not(IsValidSignature(AnnotatedSignature)), ConstructError(NotASignatureErrorTag, AnnotatedSignature),
+ using type = If(Not(IsValidSignature(AnnotatedSignature)), ConstructError(NotASignatureErrorTag, AnnotatedSignature),
+ If(Not(IsSame(RemoveAssisted(Args), Args)), ConstructError(AssistedParamInRegisterConstructorSignatureErrorTag, AnnotatedSignature),
PropagateError(CheckInjectableType(RemoveAnnotations(C)),
PropagateError(CheckInjectableTypeVector(RemoveAnnotationsFromVector(Args)),
If(IsAbstract(RemoveAnnotations(SignatureType(AnnotatedSignature))),
@@ -579,7 +579,7 @@ struct PreProcessRegisterConstructor {
RemoveAnnotations(SignatureType(AnnotatedSignature))),
If(Not(IsConstructibleWithVector(C, Args)),
ConstructError(NoConstructorMatchingInjectSignatureErrorTag, C, Signature),
- PropagateError(R, ComponentFunctorIdentity(R)))))));
+ PropagateError(R, ComponentFunctorIdentity(R))))))));
};
};
@@ -912,35 +912,45 @@ struct AutoRegisterFactoryHelper {
using R = Call(ComposeFunctors(F1, F2, F3), Comp);
struct Op {
using Result = Eval<GetResult(R)>;
+ using NakedC = UnwrapType<Eval<C>>;
void operator()(FixedSizeVector<ComponentStorageEntry>& entries) {
- using NakedC = UnwrapType<Eval<C>>;
auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
- return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
+ return UnwrapType<Eval<IFunctor>>([=](typename Args::type... args) {
NakedC* c = fun(args...).release();
NakedI* i = static_cast<NakedI*>(c);
return std::unique_ptr<NakedI>(i);
});
};
- using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
- FruitStaticAssert(IsSame(GetResult(RealOp), GetResult(R)));
- Eval<RealOp>()(entries);
+ FruitStaticAssert(IsSame(
+ GetResult(
+ Call(ComposeFunctors(
+ F1,
+ ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>),
+ ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>)),
+ Comp)),
+ GetResult(R)));
+ Eval<Call(ComposeFunctors(
+ F1,
+ ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>),
+ ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>)),
+ Comp)>()(entries);
}
std::size_t numEntries() {
#if FRUIT_EXTRA_DEBUG
- using NakedC = UnwrapType<Eval<C>>;
auto provider = [](const UnwrapType<Eval<CFunctor>>& fun) {
- return UnwrapType<Eval<IFunctor>>([=](typename TypeUnwrapper<Args>::type... args) {
+ return UnwrapType<Eval<IFunctor>>([=](typename Args::type... args) {
NakedC* c = fun(args...).release();
NakedI* i = static_cast<NakedI*>(c);
return std::unique_ptr<NakedI>(i);
});
};
- using RealF2 = ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealF3 = ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>);
- using RealOp = Call(ComposeFunctors(F1, RealF2, RealF3), Comp);
- FruitAssert(Eval<R>().numEntries() == Eval<RealOp>().numEntries());
+ FruitAssert(
+ Eval<R>().numEntries() ==
+ Eval<Call(ComposeFunctors(
+ F1, ComponentFunctor(PreProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>),
+ ComponentFunctor(PostProcessRegisterProvider, ProvidedSignature, Type<decltype(provider)>)),
+ Comp)>()
+ .numEntries());
#endif
return Eval<R>().numEntries();
}
diff --git a/include/fruit/impl/component_storage/component_storage.defn.h b/include/fruit/impl/component_storage/component_storage.defn.h
index c44efb9..0d0d4ce 100644
--- a/include/fruit/impl/component_storage/component_storage.defn.h
+++ b/include/fruit/impl/component_storage/component_storage.defn.h
@@ -23,14 +23,14 @@
namespace fruit {
namespace impl {
-inline ComponentStorage::ComponentStorage(FixedSizeVector<ComponentStorageEntry>&& entries)
+inline ComponentStorage::ComponentStorage(FixedSizeVector<ComponentStorageEntry>&& entries) noexcept
: entries(std::move(entries)) {}
inline ComponentStorage::ComponentStorage(const ComponentStorage& other) {
*this = other;
}
-inline ComponentStorage::ComponentStorage(ComponentStorage&& other) {
+inline ComponentStorage::ComponentStorage(ComponentStorage&& other) noexcept {
*this = std::move(other);
}
@@ -64,7 +64,7 @@ inline ComponentStorage& ComponentStorage::operator=(const ComponentStorage& oth
return *this;
}
-inline ComponentStorage& ComponentStorage::operator=(ComponentStorage&& other) {
+inline ComponentStorage& ComponentStorage::operator=(ComponentStorage&& other) noexcept {
entries = std::move(other.entries);
// We don't want other to have any entries after this operation because we might otherwise end up destroying those
diff --git a/include/fruit/impl/component_storage/component_storage.h b/include/fruit/impl/component_storage/component_storage.h
index 45e3f05..c3f96ae 100644
--- a/include/fruit/impl/component_storage/component_storage.h
+++ b/include/fruit/impl/component_storage/component_storage.h
@@ -43,9 +43,9 @@ private:
public:
ComponentStorage() = default;
- ComponentStorage(FixedSizeVector<ComponentStorageEntry>&& entries);
+ explicit ComponentStorage(FixedSizeVector<ComponentStorageEntry>&& entries) noexcept;
ComponentStorage(const ComponentStorage&);
- ComponentStorage(ComponentStorage&&);
+ ComponentStorage(ComponentStorage&&) noexcept;
~ComponentStorage();
@@ -54,7 +54,7 @@ public:
std::size_t numEntries() const;
ComponentStorage& operator=(const ComponentStorage&);
- ComponentStorage& operator=(ComponentStorage&&);
+ ComponentStorage& operator=(ComponentStorage&&) noexcept;
};
} // namespace impl
diff --git a/include/fruit/impl/component_storage/component_storage_entry.h b/include/fruit/impl/component_storage/component_storage_entry.h
index 80e1e48..eb64791 100644
--- a/include/fruit/impl/component_storage/component_storage_entry.h
+++ b/include/fruit/impl/component_storage/component_storage_entry.h
@@ -238,7 +238,7 @@ struct ComponentStorageEntry {
using entry_vector_t = std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>;
- ComponentInterface(erased_fun_t erased_fun);
+ explicit ComponentInterface(erased_fun_t erased_fun);
virtual ~ComponentInterface() = default;
diff --git a/include/fruit/impl/component_storage/partial_component_storage.defn.h b/include/fruit/impl/component_storage/partial_component_storage.defn.h
index 18e65e5..0e4b98c 100644
--- a/include/fruit/impl/component_storage/partial_component_storage.defn.h
+++ b/include/fruit/impl/component_storage/partial_component_storage.defn.h
@@ -46,7 +46,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
@@ -64,7 +64,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
@@ -164,7 +164,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
@@ -279,7 +279,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
@@ -297,7 +297,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
@@ -315,7 +315,7 @@ private:
PartialComponentStorage<PreviousBindings...>& previous_storage;
public:
- PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage)
+ PartialComponentStorage(PartialComponentStorage<PreviousBindings...>& previous_storage) // NOLINT(google-explicit-constructor)
: previous_storage(previous_storage) {}
void addBindings(FixedSizeVector<ComponentStorageEntry>& entries) const {
diff --git a/include/fruit/impl/data_structures/arena_allocator.h b/include/fruit/impl/data_structures/arena_allocator.h
index 3ba0521..207455d 100644
--- a/include/fruit/impl/data_structures/arena_allocator.h
+++ b/include/fruit/impl/data_structures/arena_allocator.h
@@ -53,10 +53,10 @@ public:
* Constructs an arena allocator using the specified memory pool.
* The MemoryPool object must outlive all allocators constructed with it and all allocated objects.
*/
- ArenaAllocator(MemoryPool& memory_pool);
+ explicit ArenaAllocator(MemoryPool& memory_pool);
template <typename U>
- ArenaAllocator(const ArenaAllocator<U>&);
+ ArenaAllocator(const ArenaAllocator<U>&); // NOLINT(google-explicit-constructor)
T* allocate(std::size_t n);
void deallocate(T* p, std::size_t);
diff --git a/include/fruit/impl/data_structures/fixed_size_allocator.defn.h b/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
index 7bad811..c5f6faf 100644
--- a/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
+++ b/include/fruit/impl/data_structures/fixed_size_allocator.defn.h
@@ -98,7 +98,7 @@ inline void FixedSizeAllocator::registerExternallyAllocatedObject(T* p) {
on_destruction.push_back(std::pair<destroy_t, void*>{destroyExternalObject<T>, p});
}
-inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocatorData allocator_data)
+inline FixedSizeAllocator::FixedSizeAllocator(const FixedSizeAllocatorData& allocator_data)
: on_destruction(allocator_data.num_types_to_destroy) {
// The +1 is because we waste the first byte (storage_last_used points to the beginning of storage).
storage_begin = new char[allocator_data.total_size + 1];
@@ -113,7 +113,7 @@ inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocatorData allocator_d
#endif
}
-inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocator&& x) : FixedSizeAllocator() {
+inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocator&& x) noexcept : FixedSizeAllocator() {
std::swap(storage_begin, x.storage_begin);
std::swap(storage_last_used, x.storage_last_used);
std::swap(on_destruction, x.on_destruction);
@@ -122,7 +122,7 @@ inline FixedSizeAllocator::FixedSizeAllocator(FixedSizeAllocator&& x) : FixedSiz
#endif
}
-inline FixedSizeAllocator& FixedSizeAllocator::operator=(FixedSizeAllocator&& x) {
+inline FixedSizeAllocator& FixedSizeAllocator::operator=(FixedSizeAllocator&& x) noexcept {
std::swap(storage_begin, x.storage_begin);
std::swap(storage_last_used, x.storage_last_used);
std::swap(on_destruction, x.on_destruction);
diff --git a/include/fruit/impl/data_structures/fixed_size_allocator.h b/include/fruit/impl/data_structures/fixed_size_allocator.h
index cbc8ca8..1e057d5 100644
--- a/include/fruit/impl/data_structures/fixed_size_allocator.h
+++ b/include/fruit/impl/data_structures/fixed_size_allocator.h
@@ -89,10 +89,10 @@ public:
FixedSizeAllocator() = default;
// Constructs an allocator for the type set in FixedSizeAllocatorData.
- FixedSizeAllocator(FixedSizeAllocatorData allocator_data);
+ explicit FixedSizeAllocator(const FixedSizeAllocatorData& allocator_data);
- FixedSizeAllocator(FixedSizeAllocator&&);
- FixedSizeAllocator& operator=(FixedSizeAllocator&&);
+ FixedSizeAllocator(FixedSizeAllocator&&) noexcept;
+ FixedSizeAllocator& operator=(FixedSizeAllocator&&) noexcept;
FixedSizeAllocator(const FixedSizeAllocator&) = delete;
FixedSizeAllocator& operator=(const FixedSizeAllocator&) = delete;
diff --git a/include/fruit/impl/data_structures/fixed_size_vector.defn.h b/include/fruit/impl/data_structures/fixed_size_vector.defn.h
index ed8a533..2467571 100644
--- a/include/fruit/impl/data_structures/fixed_size_vector.defn.h
+++ b/include/fruit/impl/data_structures/fixed_size_vector.defn.h
@@ -48,12 +48,12 @@ inline FixedSizeVector<T, Allocator>::~FixedSizeVector() {
}
template <typename T, typename Allocator>
-inline FixedSizeVector<T, Allocator>::FixedSizeVector(FixedSizeVector&& other) : FixedSizeVector() {
+inline FixedSizeVector<T, Allocator>::FixedSizeVector(FixedSizeVector&& other) noexcept : FixedSizeVector() {
swap(other);
}
template <typename T, typename Allocator>
-inline FixedSizeVector<T, Allocator>& FixedSizeVector<T, Allocator>::operator=(FixedSizeVector&& other) {
+inline FixedSizeVector<T, Allocator>& FixedSizeVector<T, Allocator>::operator=(FixedSizeVector&& other) noexcept {
swap(other);
return *this;
}
diff --git a/include/fruit/impl/data_structures/fixed_size_vector.h b/include/fruit/impl/data_structures/fixed_size_vector.h
index 7450bf1..c4fa21b 100644
--- a/include/fruit/impl/data_structures/fixed_size_vector.h
+++ b/include/fruit/impl/data_structures/fixed_size_vector.h
@@ -44,7 +44,7 @@ public:
using iterator = T*;
using const_iterator = const T*;
- FixedSizeVector(std::size_t capacity = 0, Allocator allocator = Allocator());
+ explicit FixedSizeVector(std::size_t capacity = 0, Allocator allocator = Allocator());
// Creates a vector with the specified size (and equal capacity) initialized with the specified value.
FixedSizeVector(std::size_t size, const T& value, Allocator allocator = Allocator());
~FixedSizeVector();
@@ -53,10 +53,10 @@ public:
FixedSizeVector(const FixedSizeVector& other) = delete;
FixedSizeVector(const FixedSizeVector& other, std::size_t capacity);
- FixedSizeVector(FixedSizeVector&& other);
+ FixedSizeVector(FixedSizeVector&& other) noexcept;
FixedSizeVector& operator=(const FixedSizeVector& other) = delete;
- FixedSizeVector& operator=(FixedSizeVector&& other);
+ FixedSizeVector& operator=(FixedSizeVector&& other) noexcept;
std::size_t size() const;
diff --git a/include/fruit/impl/data_structures/memory_pool.defn.h b/include/fruit/impl/data_structures/memory_pool.defn.h
index d4630f9..a104f95 100644
--- a/include/fruit/impl/data_structures/memory_pool.defn.h
+++ b/include/fruit/impl/data_structures/memory_pool.defn.h
@@ -28,13 +28,13 @@ namespace impl {
inline MemoryPool::MemoryPool() : first_free(nullptr), capacity(0) {}
-inline MemoryPool::MemoryPool(MemoryPool&& other)
+inline MemoryPool::MemoryPool(MemoryPool&& other) noexcept
: allocated_chunks(std::move(other.allocated_chunks)), first_free(other.first_free), capacity(other.capacity) {
// This is to be sure that we don't double-deallocate.
other.allocated_chunks.clear();
}
-inline MemoryPool& MemoryPool::operator=(MemoryPool&& other) {
+inline MemoryPool& MemoryPool::operator=(MemoryPool&& other) noexcept {
destroy();
allocated_chunks = std::move(other.allocated_chunks);
diff --git a/include/fruit/impl/data_structures/memory_pool.h b/include/fruit/impl/data_structures/memory_pool.h
index 05e4eff..13888dd 100644
--- a/include/fruit/impl/data_structures/memory_pool.h
+++ b/include/fruit/impl/data_structures/memory_pool.h
@@ -44,9 +44,9 @@ public:
MemoryPool();
MemoryPool(const MemoryPool&) = delete;
- MemoryPool(MemoryPool&&);
+ MemoryPool(MemoryPool&&) noexcept;
MemoryPool& operator=(const MemoryPool&) = delete;
- MemoryPool& operator=(MemoryPool&&);
+ MemoryPool& operator=(MemoryPool&&) noexcept;
~MemoryPool();
/**
diff --git a/include/fruit/impl/data_structures/packed_pointer_and_bool.h b/include/fruit/impl/data_structures/packed_pointer_and_bool.h
index 8ac84de..ef65e3c 100644
--- a/include/fruit/impl/data_structures/packed_pointer_and_bool.h
+++ b/include/fruit/impl/data_structures/packed_pointer_and_bool.h
@@ -41,10 +41,10 @@ public:
PackedPointerAndBool() = default;
PackedPointerAndBool(const PackedPointerAndBool&) = default;
- PackedPointerAndBool(PackedPointerAndBool&&) = default;
+ PackedPointerAndBool(PackedPointerAndBool&&) noexcept = default;
PackedPointerAndBool& operator=(const PackedPointerAndBool&) = default;
- PackedPointerAndBool& operator=(PackedPointerAndBool&&) = default;
+ PackedPointerAndBool& operator=(PackedPointerAndBool&&) noexcept = default;
T* getPointer() const;
void setPointer(T* p);
diff --git a/include/fruit/impl/data_structures/semistatic_graph.h b/include/fruit/impl/data_structures/semistatic_graph.h
index 26eaf46..92fd8a2 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.h
@@ -113,7 +113,7 @@ public:
friend class SemistaticGraph<NodeId, Node>;
- node_iterator(NodeData* itr);
+ explicit node_iterator(NodeData* itr);
public:
Node& getNode();
@@ -137,10 +137,10 @@ public:
friend class SemistaticGraph<NodeId, Node>;
- const_node_iterator(const NodeData* itr);
+ explicit const_node_iterator(const NodeData* itr);
public:
- const_node_iterator(node_iterator itr);
+ explicit const_node_iterator(node_iterator itr);
const Node& getNode();
@@ -158,7 +158,7 @@ public:
friend class SemistaticGraph<NodeId, Node>;
friend class SemistaticGraph<NodeId, Node>::node_iterator;
- edge_iterator(InternalNodeId* itr);
+ explicit edge_iterator(InternalNodeId* itr);
public:
// getNodeIterator(graph.nodes.begin()) returns the first neighbor.
@@ -189,7 +189,7 @@ public:
template <typename NodeIter>
SemistaticGraph(NodeIter first, NodeIter last, MemoryPool& memory_pool);
- SemistaticGraph(SemistaticGraph&&) = default;
+ SemistaticGraph(SemistaticGraph&&) noexcept = default;
SemistaticGraph(const SemistaticGraph&) = delete;
/**
@@ -208,7 +208,7 @@ public:
~SemistaticGraph();
SemistaticGraph& operator=(const SemistaticGraph&) = delete;
- SemistaticGraph& operator=(SemistaticGraph&&) = default;
+ SemistaticGraph& operator=(SemistaticGraph&&) noexcept = default;
// The result is unspecified. The only guarantee is that it's the right value to pass to edge_iterator's
// getNodeIterator() methods.
diff --git a/include/fruit/impl/data_structures/semistatic_map.h b/include/fruit/impl/data_structures/semistatic_map.h
index cd03cc2..1ccb00a 100644
--- a/include/fruit/impl/data_structures/semistatic_map.h
+++ b/include/fruit/impl/data_structures/semistatic_map.h
@@ -46,8 +46,10 @@ private:
static constexpr unsigned char beta = 4;
+ // The parentheses around std::numeric_limits<NumBits>::max are needed to workaround an issue in Windows where
+ // max is defined as a macro by a common system header. See https://github.com/google/fruit/issues/127.
static_assert(
- std::numeric_limits<NumBits>::max() >= sizeof(Unsigned) * CHAR_BIT,
+ (std::numeric_limits<NumBits>::max)() >= sizeof(Unsigned) * CHAR_BIT,
"An unsigned char is not enough to contain the number of bits in your platform. Please report this issue.");
struct HashFunction {
@@ -102,12 +104,12 @@ public:
SemistaticMap(const SemistaticMap<Key, Value>& map,
std::vector<value_type, ArenaAllocator<value_type>>&& new_elements);
- SemistaticMap(SemistaticMap&&) = default;
+ SemistaticMap(SemistaticMap&&) noexcept = default;
SemistaticMap(const SemistaticMap&) = delete;
~SemistaticMap();
- SemistaticMap& operator=(SemistaticMap&&) = default;
+ SemistaticMap& operator=(SemistaticMap&&) noexcept = default;
SemistaticMap& operator=(const SemistaticMap&) = delete;
// Precondition: `key' must exist in the map.
diff --git a/include/fruit/impl/injection_errors.h b/include/fruit/impl/injection_errors.h
index a0e9def..68247d2 100644
--- a/include/fruit/impl/injection_errors.h
+++ b/include/fruit/impl/injection_errors.h
@@ -124,6 +124,16 @@ struct NotASignatureError {
"the form MyClass(int, float).");
};
+template <typename CandidateSignature>
+struct AssistedParamInRegisterConstructorSignatureError {
+ static_assert(AlwaysFalse<CandidateSignature>::value,
+ "CandidateSignature was used as signature for a registerConstructor() (explicit or implicit via the "
+ "INJECT macro / Inject typedef) but it contains an assisted parameter. When using assisted parameters"
+ "You need to inject a factory like std::function<std::unique_ptr<MyClass>(int, float)> instead of "
+ "injecting MyClass directly. If you used an explicit registerConstructor(), you also need to switch "
+ "that to registerFactory().");
+};
+
template <typename CandidateLambda>
struct NotALambdaError {
static_assert(AlwaysFalse<CandidateLambda>::value,
@@ -494,6 +504,11 @@ struct NotASignatureErrorTag {
using apply = NotASignatureError<CandidateSignature>;
};
+struct AssistedParamInRegisterConstructorSignatureErrorTag {
+ template <typename CandidateSignature>
+ using apply = AssistedParamInRegisterConstructorSignatureError<CandidateSignature>;
+};
+
struct NotALambdaErrorTag {
template <typename CandidateLambda>
using apply = NotALambdaError<CandidateLambda>;
diff --git a/include/fruit/impl/injector/injector_storage.defn.h b/include/fruit/impl/injector/injector_storage.defn.h
index 2474ada..7494fce 100644
--- a/include/fruit/impl/injector/injector_storage.defn.h
+++ b/include/fruit/impl/injector/injector_storage.defn.h
@@ -49,7 +49,7 @@ inline bool InjectorStorage::BindingDataNodeIter::operator!=(const BindingDataNo
return itr != other.itr;
}
-inline std::ptrdiff_t InjectorStorage::BindingDataNodeIter::operator-(BindingDataNodeIter other) const {
+inline std::ptrdiff_t InjectorStorage::BindingDataNodeIter::operator-(const BindingDataNodeIter& other) const {
return itr - other.itr;
}
diff --git a/include/fruit/impl/injector/injector_storage.h b/include/fruit/impl/injector/injector_storage.h
index e9af2da..902b43b 100644
--- a/include/fruit/impl/injector/injector_storage.h
+++ b/include/fruit/impl/injector/injector_storage.h
@@ -26,6 +26,7 @@
#include <vector>
#include <mutex>
#include <thread>
+#include <fruit/impl/normalized_component_storage/normalized_component_storage_holder.h>
namespace fruit {
namespace impl {
@@ -218,7 +219,7 @@ public:
bool operator==(const BindingDataNodeIter& other) const;
bool operator!=(const BindingDataNodeIter& other) const;
- std::ptrdiff_t operator-(BindingDataNodeIter other) const;
+ std::ptrdiff_t operator-(const BindingDataNodeIter& other) const;
TypeId getId();
NormalizedBinding getValue();
diff --git a/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h b/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
index 1c9b485..19396c8 100644
--- a/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
+++ b/include/fruit/impl/normalized_component_storage/binding_normalization.templates.h
@@ -26,8 +26,6 @@
#include <fruit/impl/normalized_component_storage/binding_normalization.h>
#include <fruit/impl/util/type_info.h>
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
@@ -193,7 +191,7 @@ BindingNormalization::handleBindingForConstructedObject(BindingNormalizationCont
}
// New binding, add it to the map.
- entry_in_map = std::move(entry);
+ entry_in_map = entry;
}
template <typename... Params>
@@ -227,7 +225,7 @@ FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleBindingForObjectToCo
}
// New binding, add it to the map.
- entry_in_map = std::move(entry);
+ entry_in_map = entry;
}
template <typename... Params>
@@ -261,7 +259,7 @@ FRUIT_ALWAYS_INLINE inline void BindingNormalization::handleBindingForObjectToCo
}
// New binding, add it to the map.
- entry_in_map = std::move(entry);
+ entry_in_map = entry;
}
template <typename... Params>
@@ -313,7 +311,7 @@ BindingNormalization::handleComponentWithoutArgsEndMarker(BindingNormalizationCo
// components_with_*_with_expansion_in_progress to fully_expanded_components_*.
context.components_with_no_args_with_expansion_in_progress.erase(entry.lazy_component_with_no_args);
- context.fully_expanded_components_with_no_args.insert(std::move(entry.lazy_component_with_no_args));
+ context.fully_expanded_components_with_no_args.insert(entry.lazy_component_with_no_args);
}
template <typename... Params>
@@ -326,14 +324,14 @@ BindingNormalization::handleComponentWithArgsEndMarker(BindingNormalizationConte
// components_with_*_with_expansion_in_progress to fully_expanded_components_*.
context.components_with_args_with_expansion_in_progress.erase(entry.lazy_component_with_args);
- context.fully_expanded_components_with_args.insert(std::move(entry.lazy_component_with_args));
+ context.fully_expanded_components_with_args.insert(entry.lazy_component_with_args);
}
template <typename... Params>
void BindingNormalization::handleReplacedLazyComponentWithArgs(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_ARGS);
- ComponentStorageEntry replaced_component_entry = std::move(entry);
+ ComponentStorageEntry replaced_component_entry = entry;
context.entries_to_process.pop_back();
FruitAssert(!context.entries_to_process.empty());
@@ -343,10 +341,10 @@ void BindingNormalization::handleReplacedLazyComponentWithArgs(BindingNormalizat
ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
- if (context.components_with_args_with_expansion_in_progress.count(entry.lazy_component_with_args) != 0 ||
- context.fully_expanded_components_with_args.count(entry.lazy_component_with_args) != 0 ||
+ if (context.components_with_args_with_expansion_in_progress.count(replaced_component_entry.lazy_component_with_args) != 0 ||
+ context.fully_expanded_components_with_args.count(replaced_component_entry.lazy_component_with_args) != 0 ||
context.functors.is_component_with_args_already_expanded_in_normalized_component(
- entry.lazy_component_with_args)) {
+ replaced_component_entry.lazy_component_with_args)) {
printComponentReplacementFailedBecauseTargetAlreadyExpanded(replaced_component_entry, replacement_component_entry);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -379,7 +377,7 @@ template <typename... Params>
void BindingNormalization::handleReplacedLazyComponentWithNoArgs(BindingNormalizationContext<Params...>& context) {
ComponentStorageEntry entry = context.entries_to_process.back();
FruitAssert(entry.kind == ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_NO_ARGS);
- ComponentStorageEntry replaced_component_entry = std::move(entry);
+ ComponentStorageEntry replaced_component_entry = entry;
context.entries_to_process.pop_back();
FruitAssert(!context.entries_to_process.empty());
@@ -389,10 +387,10 @@ void BindingNormalization::handleReplacedLazyComponentWithNoArgs(BindingNormaliz
ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
replacement_component_entry.kind == ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS);
- if (context.components_with_no_args_with_expansion_in_progress.count(entry.lazy_component_with_no_args) != 0 ||
- context.fully_expanded_components_with_no_args.count(entry.lazy_component_with_no_args) != 0 ||
+ if (context.components_with_no_args_with_expansion_in_progress.count(replaced_component_entry.lazy_component_with_no_args) != 0 ||
+ context.fully_expanded_components_with_no_args.count(replaced_component_entry.lazy_component_with_no_args) != 0 ||
context.functors.is_component_with_no_args_already_expanded_in_normalized_component(
- entry.lazy_component_with_no_args)) {
+ replaced_component_entry.lazy_component_with_no_args)) {
printComponentReplacementFailedBecauseTargetAlreadyExpanded(replaced_component_entry, replacement_component_entry);
FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
}
@@ -626,7 +624,7 @@ BindingNormalization::performBindingCompression(
auto c_binding_data = binding_data_map.find(c_id);
FruitAssert(i_binding_data != binding_data_map.end());
FruitAssert(c_binding_data != binding_data_map.end());
- NormalizedComponentStorage::CompressedBindingUndoInfo undo_info;
+ NormalizedComponentStorage::CompressedBindingUndoInfo undo_info{};
undo_info.i_type_id = i_id;
FruitAssert(i_binding_data->second.kind ==
ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION);
diff --git a/include/fruit/impl/normalized_component_storage/normalized_component_storage.h b/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
index 22dc8b1..9ec987e 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_component_storage.h
@@ -157,7 +157,7 @@ public:
// We don't use the default destructor because that will require the inclusion of
// the Boost's hashmap header. We define this in the cpp file instead.
- ~NormalizedComponentStorage();
+ ~NormalizedComponentStorage() noexcept;
};
} // namespace impl
diff --git a/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h b/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
index 180f297..6c07680 100644
--- a/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
+++ b/include/fruit/impl/normalized_component_storage/normalized_component_storage_holder.h
@@ -45,7 +45,8 @@ public:
struct WithUndoableCompression {};
struct WithPermanentCompression {};
- NormalizedComponentStorageHolder() = default;
+ NormalizedComponentStorageHolder() noexcept = default;
+
/**
* The MemoryPool is only used during construction, the constructed object *can* outlive the memory pool.
@@ -62,7 +63,7 @@ public:
// We don't use the default destructor because that would require the inclusion of
// normalized_component_storage.h. We define this in the cpp file instead.
- ~NormalizedComponentStorageHolder();
+ ~NormalizedComponentStorageHolder() noexcept;
};
} // namespace impl
diff --git a/include/fruit/impl/util/hash_helpers.defn.h b/include/fruit/impl/util/hash_helpers.defn.h
index e75ec4a..2f7544c 100644
--- a/include/fruit/impl/util/hash_helpers.defn.h
+++ b/include/fruit/impl/util/hash_helpers.defn.h
@@ -68,7 +68,7 @@ inline HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator>
createHashMapWithArenaAllocatorAndCustomFunctors(size_t capacity, MemoryPool& memory_pool, Hasher hasher,
EqualityComparator equality_comparator) {
return HashMapWithArenaAllocator<Key, Value, Hasher, EqualityComparator>(
- capacity, hasher, equality_comparator, ArenaAllocator<std::pair<const Key, Value>>(memory_pool));
+ capacity, hasher, equality_comparator, ArenaAllocator<std::pair<const Key, Value>>{memory_pool});
}
} // namespace impl
diff --git a/include/fruit/impl/util/lambda_invoker.h b/include/fruit/impl/util/lambda_invoker.h
index 2c8d63e..afe0a19 100644
--- a/include/fruit/impl/util/lambda_invoker.h
+++ b/include/fruit/impl/util/lambda_invoker.h
@@ -31,21 +31,31 @@
namespace fruit {
namespace impl {
+template <typename T>
+struct SafeAlignmentOf {
+ constexpr static const std::size_t value = alignof(T);
+};
+
+template <typename T, typename... Args>
+struct SafeAlignmentOf<T(Args...)> {
+ constexpr static const std::size_t value = alignof(int);
+};
+
class LambdaInvoker {
public:
template <typename F, typename... Args>
- FRUIT_ALWAYS_INLINE static auto invoke(Args&&... args)
+ FRUIT_ALWAYS_INLINE static auto invoke(Args&&... args)
-> decltype(std::declval<const F&>()(std::declval<Args>()...)) {
// We reinterpret-cast a char[] to avoid de-referencing nullptr, which would technically be
// undefined behavior (even though we would not access any data there anyway).
// Sharing this buffer for different types F would also be undefined behavior since we'd break
// strict aliasing between those types.
- alignas(alignof(F)) static char buf[1];
+ alignas(SafeAlignmentOf<F>::value) static char buf[1];
FruitStaticAssert(fruit::impl::meta::IsEmpty(fruit::impl::meta::Type<F>));
FruitStaticAssert(fruit::impl::meta::IsTriviallyCopyable(fruit::impl::meta::Type<F>));
// Since `F' is empty, a valid value of type F is already stored at the beginning of buf.
- F* f = reinterpret_cast<F*>(buf);
+ F* f = reinterpret_cast<F*>((char*)buf);
return (*f)(std::forward<Args>(args)...);
}
};
diff --git a/include/fruit/impl/util/type_info.defn.h b/include/fruit/impl/util/type_info.defn.h
index d52fab0..d077b02 100644
--- a/include/fruit/impl/util/type_info.defn.h
+++ b/include/fruit/impl/util/type_info.defn.h
@@ -147,7 +147,7 @@ struct GetTypeIdsForListHelper;
template <typename... Ts>
struct GetTypeIdsForListHelper<fruit::impl::meta::Vector<Ts...>> {
std::vector<TypeId, ArenaAllocator<TypeId>> operator()(MemoryPool& memory_pool) {
- return std::vector<TypeId, ArenaAllocator<TypeId>>(std::initializer_list<TypeId>{getTypeId<Ts>()...}, memory_pool);
+ return std::vector<TypeId, ArenaAllocator<TypeId>>(std::initializer_list<TypeId>{getTypeId<Ts>()...}, ArenaAllocator<TypeId>{memory_pool});
}
};
diff --git a/include/fruit/impl/util/type_info.h b/include/fruit/impl/util/type_info.h
index 01fb647..5a9d079 100644
--- a/include/fruit/impl/util/type_info.h
+++ b/include/fruit/impl/util/type_info.h
@@ -42,7 +42,7 @@ struct alignas(1) alignas(void*) TypeInfo {
};
// This should only be used if RTTI is disabled. Use the other constructor if possible.
- constexpr TypeInfo(ConcreteTypeInfo concrete_type_info);
+ explicit constexpr TypeInfo(ConcreteTypeInfo concrete_type_info);
constexpr TypeInfo(const std::type_info& info, ConcreteTypeInfo concrete_type_info);
@@ -64,7 +64,7 @@ private:
struct TypeId {
const TypeInfo* type_info;
- operator std::string() const;
+ explicit operator std::string() const;
bool operator==(TypeId x) const;
bool operator!=(TypeId x) const;
diff --git a/include/fruit/injector.h b/include/fruit/injector.h
index a62f631..e84112a 100644
--- a/include/fruit/injector.h
+++ b/include/fruit/injector.h
@@ -48,7 +48,7 @@ template <typename... P>
class Injector {
public:
// Moving injectors is allowed.
- Injector(Injector&&) = default;
+ Injector(Injector&&) noexcept = default;
// Copying injectors is forbidden.
Injector(const Injector&) = delete;
@@ -79,7 +79,7 @@ public:
* Foo* foo = injector.get<Foo*>();
*/
template <typename... FormalArgs, typename... Args>
- Injector(Component<P...> (*)(FormalArgs...), Args&&... args);
+ explicit Injector(Component<P...> (*)(FormalArgs...), Args&&... args);
/**
* This creates an injector from a normalized component and a component function.
diff --git a/include/fruit/normalized_component.h b/include/fruit/normalized_component.h
index 105edf8..e9dca2f 100644
--- a/include/fruit/normalized_component.h
+++ b/include/fruit/normalized_component.h
@@ -111,9 +111,9 @@ public:
* The constraints on the argument types (if there are any) are the same as the ones for PartialComponent::install().
*/
template <typename... FormalArgs, typename... Args>
- NormalizedComponent(Component<Params...> (*)(FormalArgs...), Args&&... args);
+ explicit NormalizedComponent(Component<Params...> (*)(FormalArgs...), Args&&... args);
- NormalizedComponent(NormalizedComponent&&) = default;
+ NormalizedComponent(NormalizedComponent&& storage) noexcept : storage(std::move(storage.storage)) {}
NormalizedComponent(const NormalizedComponent&) = delete;
NormalizedComponent& operator=(NormalizedComponent&&) = delete;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 66bf79f..0e328cf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,5 +22,6 @@ else()
endif()
install(TARGETS fruit
- ARCHIVE DESTINATION "${INSTALL_LIBRARY_DIR}"
- LIBRARY DESTINATION "${INSTALL_LIBRARY_DIR}")
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
diff --git a/src/binding_normalization.cpp b/src/binding_normalization.cpp
index c353687..db6ee00 100644
--- a/src/binding_normalization.cpp
+++ b/src/binding_normalization.cpp
@@ -32,8 +32,6 @@
using std::cout;
using std::endl;
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
@@ -242,7 +240,7 @@ void BindingNormalization::addMultibindings(std::unordered_map<TypeId, Normalize
NormalizedMultibinding normalized_multibinding;
normalized_multibinding.is_constructed = true;
normalized_multibinding.object = i->first.multibinding_for_constructed_object.object_ptr;
- b.elems.push_back(std::move(normalized_multibinding));
+ b.elems.push_back(normalized_multibinding);
} break;
case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION: {
@@ -250,7 +248,7 @@ void BindingNormalization::addMultibindings(std::unordered_map<TypeId, Normalize
NormalizedMultibinding normalized_multibinding;
normalized_multibinding.is_constructed = false;
normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
- b.elems.push_back(std::move(normalized_multibinding));
+ b.elems.push_back(normalized_multibinding);
} break;
case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION: {
@@ -258,7 +256,7 @@ void BindingNormalization::addMultibindings(std::unordered_map<TypeId, Normalize
NormalizedMultibinding normalized_multibinding;
normalized_multibinding.is_constructed = false;
normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
- b.elems.push_back(std::move(normalized_multibinding));
+ b.elems.push_back(normalized_multibinding);
} break;
default:
@@ -292,21 +290,21 @@ void BindingNormalization::normalizeBindingsWithUndoableBindingCompression(
[&bindingCompressionInfoMap](TypeId c_type_id, NormalizedComponentStorage::CompressedBindingUndoInfo undo_info) {
bindingCompressionInfoMap[c_type_id] = undo_info;
},
- [&fully_expanded_components_with_no_args](LazyComponentWithNoArgsSet& fully_expanded_components) {
+ [&fully_expanded_components_with_no_args, &memory_pool](LazyComponentWithNoArgsSet& fully_expanded_components) {
fully_expanded_components_with_no_args = std::move(fully_expanded_components);
- fully_expanded_components.clear();
+ fully_expanded_components = NormalizedComponentStorage::createLazyComponentWithNoArgsSet(0, memory_pool);
},
- [&fully_expanded_components_with_args](LazyComponentWithArgsSet& fully_expanded_components) {
+ [&fully_expanded_components_with_args, &memory_pool](LazyComponentWithArgsSet& fully_expanded_components) {
fully_expanded_components_with_args = std::move(fully_expanded_components);
- fully_expanded_components.clear();
+ fully_expanded_components = NormalizedComponentStorage::createLazyComponentWithArgsSet(0, memory_pool);
},
- [&component_with_no_args_replacements](LazyComponentWithNoArgsReplacementMap& component_replacements) {
+ [&component_with_no_args_replacements, &memory_pool](LazyComponentWithNoArgsReplacementMap& component_replacements) {
component_with_no_args_replacements = std::move(component_replacements);
- component_replacements.clear();
+ component_replacements = NormalizedComponentStorage::createLazyComponentWithNoArgsReplacementMap(0, memory_pool);
},
- [&component_with_args_replacements](LazyComponentWithArgsReplacementMap& component_replacements) {
+ [&component_with_args_replacements, &memory_pool](LazyComponentWithArgsReplacementMap& component_replacements) {
component_with_args_replacements = std::move(component_replacements);
- component_replacements.clear();
+ component_replacements = NormalizedComponentStorage::createLazyComponentWithArgsReplacementMap(0, memory_pool);
});
}
@@ -435,9 +433,9 @@ void BindingNormalization::normalizeBindingsAndAddTo(
i_binding.kind = ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION;
i_binding.binding_for_object_to_construct = binding_compression_itr->second.i_binding;
- new_bindings_vector.push_back(std::move(c_binding));
+ new_bindings_vector.push_back(c_binding);
// This TypeId is already in normalized_component.bindings, we overwrite it here.
- new_bindings_vector.push_back(std::move(i_binding));
+ new_bindings_vector.push_back(i_binding);
#if FRUIT_EXTRA_DEBUG
std::cout << "InjectorStorage: undoing binding compression for: " << binding_compression_itr->second.i_type_id
diff --git a/src/fixed_size_allocator.cpp b/src/fixed_size_allocator.cpp
index b490828..2652885 100644
--- a/src/fixed_size_allocator.cpp
+++ b/src/fixed_size_allocator.cpp
@@ -19,8 +19,6 @@
#include <fruit/impl/data_structures/fixed_size_allocator.h>
#include <fruit/impl/data_structures/fixed_size_vector.templates.h>
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
diff --git a/src/injector_storage.cpp b/src/injector_storage.cpp
index 1e77702..af3a14d 100644
--- a/src/injector_storage.cpp
+++ b/src/injector_storage.cpp
@@ -32,8 +32,6 @@
using std::cout;
using std::endl;
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
diff --git a/src/memory_pool.cpp b/src/memory_pool.cpp
index 1311b2c..03429c2 100644
--- a/src/memory_pool.cpp
+++ b/src/memory_pool.cpp
@@ -18,9 +18,7 @@
#include <fruit/impl/data_structures/memory_pool.h>
-using namespace fruit::impl;
-
-void MemoryPool::destroy() {
+void fruit::impl::MemoryPool::destroy() {
for (void* p : allocated_chunks) {
operator delete(p);
}
diff --git a/src/normalized_component_storage.cpp b/src/normalized_component_storage.cpp
index 7449ec5..59d01ca 100644
--- a/src/normalized_component_storage.cpp
+++ b/src/normalized_component_storage.cpp
@@ -34,9 +34,6 @@
using std::cout;
using std::endl;
-using namespace fruit;
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
@@ -94,7 +91,7 @@ NormalizedComponentStorage::NormalizedComponentStorage(ComponentStorage&& compon
memory_pool);
}
-NormalizedComponentStorage::~NormalizedComponentStorage() {
+NormalizedComponentStorage::~NormalizedComponentStorage() noexcept {
for (auto& x : fully_expanded_components_with_args) {
x.destroy();
}
diff --git a/src/normalized_component_storage_holder.cpp b/src/normalized_component_storage_holder.cpp
index 0629b99..dfc4fd3 100644
--- a/src/normalized_component_storage_holder.cpp
+++ b/src/normalized_component_storage_holder.cpp
@@ -19,9 +19,6 @@
#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>
#include <fruit/impl/normalized_component_storage/normalized_component_storage_holder.h>
-using namespace fruit;
-using namespace fruit::impl;
-
namespace fruit {
namespace impl {
@@ -31,7 +28,7 @@ NormalizedComponentStorageHolder::NormalizedComponentStorageHolder(
: storage(new NormalizedComponentStorage(std::move(component), exposed_types, memory_pool,
NormalizedComponentStorage::WithUndoableCompression())) {}
-NormalizedComponentStorageHolder::~NormalizedComponentStorageHolder() {}
+NormalizedComponentStorageHolder::~NormalizedComponentStorageHolder() noexcept {}
} // namespace impl
} // namespace fruit
diff --git a/src/semistatic_graph.cpp b/src/semistatic_graph.cpp
index 1b23d70..71952f5 100644
--- a/src/semistatic_graph.cpp
+++ b/src/semistatic_graph.cpp
@@ -22,8 +22,6 @@
#include <fruit/impl/normalized_component_storage/normalized_bindings.h>
#include <fruit/impl/util/type_info.h>
-using namespace fruit::impl;
-
// Clang requires the following instantiation to be in its namespace.
namespace fruit {
namespace impl {
diff --git a/src/semistatic_map.cpp b/src/semistatic_map.cpp
index 281f34a..15778a0 100644
--- a/src/semistatic_map.cpp
+++ b/src/semistatic_map.cpp
@@ -22,8 +22,6 @@
#include <fruit/impl/util/type_info.h>
-using namespace fruit::impl;
-
// Clang requires the following instantiation to be in its namespace.
namespace fruit {
namespace impl {
diff --git a/tests/BUILD b/tests/BUILD
index 4fc016d..e89f144 100644
--- a/tests/BUILD
+++ b/tests/BUILD
@@ -15,10 +15,14 @@ filegroup(
cc_library(
name = "test_headers",
- srcs = [],
+ srcs = ["test_common.cpp"],
hdrs = TEST_HEADERS,
visibility = ["//third_party/fruit/tests:__subpackages__"],
includes = ["."],
+ deps = [
+ "//third_party/fruit",
+ "@boost//:unordered",
+ ]
)
[cc_test(
@@ -30,7 +34,7 @@ cc_library(
]
) for filename in glob(
["*.cpp"],
- exclude = ["include_test.cpp"])]
+ exclude = ["include_test.cpp", "test_common.cpp"])]
FRUIT_PUBLIC_HEADERS = [
"component",
@@ -47,13 +51,15 @@ genrule(
srcs = [
"//third_party/fruit",
"//third_party/fruit:fruit_headers",
+ ":test_headers",
":test_headers_filegroup",
],
- # Here we copy libfruit.so to work around an issue with py_test where the outputs of a cc_library in the data
- # attribute of a py_test are not taken into account.
+ # Here we copy libfruit.so and test_headers.so to work around an issue with py_test where the outputs of a
+ # cc_library in the data attribute of a py_test are not taken into account.
outs = [
"fruit_test_config.py",
- "libfruit.so"
+ "libfruit.so",
+ "libtest_headers_copy.so",
],
toolchains = [
# For $(CC_FLAGS)
@@ -63,10 +69,11 @@ genrule(
],
visibility = ["//third_party/fruit/tests:__subpackages__"],
cmd = ""
- + "FRUIT_HEADERS_LOCATION=`for f in $(locations //third_party/fruit:fruit_headers); do echo \"$$f\"; done | fgrep configuration/bazel/ | head -n 1 | sed 's|configuration/bazel/.*|./|'`;"
+ "TEST_HEADERS_LOCATION=`for f in $(locations :test_headers_filegroup); do echo \"$$f\"; done | fgrep test_macros.h | sed 's|test_macros.h|./|'`;"
+ "LIBFRUIT_LOCATION=`for f in $(locations //third_party/fruit); do echo \"$$f\"; done | fgrep libfruit.so | head -n 1 | sed 's|libfruit.so|./|'`;"
+ + "LIBTEST_HEADERS_LOCATION=`for f in $(locations //third_party/fruit/tests:test_headers); do echo \"$$f\"; done | fgrep libtest_headers.so | head -n 1 | sed 's|libtest_headers.so|./|'`;"
+ "cp $${LIBFRUIT_LOCATION}/libfruit.so $(@D)/;"
+ + "cp $${LIBTEST_HEADERS_LOCATION}/libtest_headers.so $(@D)/libtest_headers_copy.so;"
+ "echo -e \""
+ "CXX='$(CC)'\n"
+ "CXX_COMPILER_NAME='GNU'\n"
@@ -76,8 +83,10 @@ genrule(
+ "CMAKE_BUILD_TYPE=None\n"
+ "PATH_TO_COMPILED_FRUIT='third_party/fruit/tests'\n"
+ "PATH_TO_COMPILED_FRUIT_LIB='third_party/fruit/tests'\n"
- + "PATH_TO_FRUIT_STATIC_HEADERS='$${FRUIT_HEADERS_LOCATION}/include'\n"
- + "PATH_TO_FRUIT_GENERATED_HEADERS='$${FRUIT_HEADERS_LOCATION}/configuration/bazel'\n"
+ + "PATH_TO_COMPILED_TEST_HEADERS='third_party/fruit/tests/test_headers'\n"
+ + "PATH_TO_COMPILED_TEST_HEADERS_LIB='third_party/fruit/tests/test_headers'\n"
+ + "PATH_TO_FRUIT_STATIC_HEADERS='third_party/fruit/include'\n"
+ + "PATH_TO_FRUIT_GENERATED_HEADERS='third_party/fruit/configuration/bazel'\n"
+ "PATH_TO_FRUIT_TEST_HEADERS='$${TEST_HEADERS_LOCATION}'\n"
+ "ADDITIONAL_LINKER_FLAGS='-lstdc++ -lm'\n"
+ "RUN_TESTS_UNDER_VALGRIND='0'\n"
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b5cbfdb..095d3db 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -81,13 +81,19 @@ if("${CMAKE_CXX_COMPILER_ID}" MATCHES "^(MSVC)$")
set(FRUIT_TESTONLY_CXXFLAGS "${FRUIT_TESTONLY_CXXFLAGS} /wd4702 /wd4503")
endif()
+add_library(test_headers_copy STATIC test_common.cpp)
+target_link_libraries(test_headers_copy fruit)
+
+# Escape the backslash which is a Windows path separator.
+string(REPLACE "\\" "\\\\" ADDITIONAL_INCLUDE_DIRS "${Boost_INCLUDE_DIRS}")
+
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/fruit_test_config.py"
CONTENT "
CXX='${CMAKE_CXX_COMPILER}'
CXX_COMPILER_NAME='${CMAKE_CXX_COMPILER_ID}'
CXX_COMPILER_VERSION='${CMAKE_CXX_COMPILER_VERSION}'
FRUIT_COMPILE_FLAGS='${FRUIT_COMPILE_FLAGS} ${FRUIT_TESTONLY_CXXFLAGS}'
-ADDITIONAL_INCLUDE_DIRS='${BOOST_DIR}'
+ADDITIONAL_INCLUDE_DIRS='${ADDITIONAL_INCLUDE_DIRS}'
ADDITIONAL_LINKER_FLAGS='${CMAKE_EXE_LINKER_FLAGS}'
RUN_TESTS_UNDER_VALGRIND='${RUN_TESTS_UNDER_VALGRIND_FLAG}'
VALGRIND_FLAGS='${VALGRIND_FLAGS_STR}'
@@ -95,6 +101,8 @@ CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}'
PATH_TO_COMPILED_FRUIT='$<TARGET_FILE_DIR:fruit>'
PATH_TO_COMPILED_FRUIT_LIB='$<TARGET_FILE:fruit>'
+PATH_TO_COMPILED_TEST_HEADERS='$<TARGET_FILE_DIR:test_headers_copy>'
+PATH_TO_COMPILED_TEST_HEADERS_LIB='$<TARGET_FILE:test_headers_copy>'
PATH_TO_FRUIT_STATIC_HEADERS='${CMAKE_CURRENT_SOURCE_DIR}/../include'
PATH_TO_FRUIT_GENERATED_HEADERS='${CMAKE_CURRENT_BINARY_DIR}/../include'
PATH_TO_FRUIT_TEST_HEADERS='${CMAKE_CURRENT_SOURCE_DIR}'
@@ -106,4 +114,5 @@ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pytest.ini"
[pytest]
testpaths = \"${CMAKE_CURRENT_SOURCE_DIR}\"
addopts = -r a
+timeout = 300
")
diff --git a/tests/build_defs.bzl b/tests/build_defs.bzl
index 13d3005..05bd13c 100644
--- a/tests/build_defs.bzl
+++ b/tests/build_defs.bzl
@@ -12,6 +12,7 @@ def fruit_py_tests(srcs, data=[]):
data = data + [
"//third_party/fruit:fruit_headers",
"//third_party/fruit/tests:libfruit.so",
+ "//third_party/fruit/tests:libtest_headers_copy.so",
"//third_party/fruit/tests:test_headers_filegroup",
],
shard_count = 32,
diff --git a/tests/data_structures/test_semistatic_graph.py b/tests/data_structures/test_semistatic_graph.py
index e0510da..95629e7 100644
--- a/tests/data_structures/test_semistatic_graph.py
+++ b/tests/data_structures/test_semistatic_graph.py
@@ -19,30 +19,10 @@ from fruit_test_common import *
COMMON_DEFINITIONS = '''
#include "test_common.h"
- #define IN_FRUIT_CPP_FILE 1
- #include <fruit/impl/data_structures/semistatic_graph.templates.h>
-
using namespace std;
using namespace fruit::impl;
- using Graph = SemistaticGraph<int, const char*>;
- using node_iterator = Graph::node_iterator;
- using edge_iterator = Graph::edge_iterator;
-
vector<int> no_neighbors{};
-
- struct SimpleNode {
- int id;
- const char* value;
- const vector<int>* neighbors;
- bool is_terminal;
-
- int getId() { return id; }
- const char* getValue() { return value; }
- bool isTerminal() { return is_terminal; }
- vector<int>::const_iterator getEdgesBegin() { return neighbors->begin(); }
- vector<int>::const_iterator getEdgesEnd() { return neighbors->end(); }
- };
'''
class TestSemistaticGraph(parameterized.TestCase):
diff --git a/tests/fruit_test_common.py b/tests/fruit_test_common.py
index 28ecc59..36e5b20 100644
--- a/tests/fruit_test_common.py
+++ b/tests/fruit_test_common.py
@@ -35,7 +35,7 @@ run_under_valgrind = RUN_TESTS_UNDER_VALGRIND.lower() not in ('false', 'off', 'n
def pretty_print_command(command, env):
return 'cd %s; env -i %s %s' % (
- shlex.quote(env['PWD']),
+ shlex.quote(os.getcwd()),
' '.join('%s=%s' % (var_name, shlex.quote(value)) for var_name, value in env.items() if var_name != 'PWD'),
' '.join(shlex.quote(x) for x in command))
@@ -166,7 +166,7 @@ class MsvcCompiler:
self._compile(include_dirs, args = args)
except CommandFailedException as e:
# Note that we use stdout here, unlike above. MSVC reports compilation warnings and errors on stdout.
- raise CompilationFailedException(e.command, e.stdout)
+ raise CompilationFailedException(e.command, e.env, e.stdout)
def compile_and_link(self, source, include_dirs, output_file_name, args=[]):
self._compile(
@@ -200,14 +200,21 @@ if CXX_COMPILER_NAME == 'MSVC':
path_to_fruit_lib = PATH_TO_COMPILED_FRUIT_LIB[:-4] + '.lib'
else:
path_to_fruit_lib = PATH_TO_COMPILED_FRUIT_LIB
- fruit_tests_linker_flags = [path_to_fruit_lib]
+ if PATH_TO_COMPILED_TEST_HEADERS_LIB.endswith('.dll'):
+ path_to_test_headers_lib = PATH_TO_COMPILED_TEST_HEADERS_LIB[:-4] + '.lib'
+ else:
+ path_to_test_headers_lib = PATH_TO_COMPILED_TEST_HEADERS_LIB
+ fruit_tests_linker_flags = [path_to_fruit_lib, path_to_test_headers_lib]
fruit_error_message_extraction_regex = 'error C2338: (.*)'
else:
compiler = PosixCompiler()
fruit_tests_linker_flags = [
'-lfruit',
+ '-ltest_headers_copy',
'-L' + PATH_TO_COMPILED_FRUIT,
'-Wl,-rpath,' + PATH_TO_COMPILED_FRUIT,
+ '-L' + PATH_TO_COMPILED_TEST_HEADERS,
+ '-Wl,-rpath,' + PATH_TO_COMPILED_TEST_HEADERS,
]
fruit_error_message_extraction_regex = 'static.assert(.*)'
@@ -222,9 +229,12 @@ _assert_helper = unittest.TestCase()
def modify_env_for_compiled_executables(env):
env = env.copy()
path_to_fruit_lib_dir = os.path.dirname(PATH_TO_COMPILED_FRUIT_LIB)
+ path_to_fruit_test_headers_dir = os.path.dirname(PATH_TO_COMPILED_TEST_HEADERS_LIB)
print('PATH_TO_COMPILED_FRUIT_LIB:', PATH_TO_COMPILED_FRUIT_LIB)
+ print('PATH_TO_COMPILED_TEST_HEADERS_LIB:', PATH_TO_COMPILED_TEST_HEADERS_LIB)
print('Adding directory to PATH:', path_to_fruit_lib_dir)
- env["PATH"] += os.pathsep + path_to_fruit_lib_dir
+ print('Adding directory to PATH:', path_to_fruit_test_headers_dir)
+ env["PATH"] += os.pathsep + path_to_fruit_lib_dir + os.pathsep + path_to_fruit_test_headers_dir
return env
def _create_temporary_file(file_content, file_name_suffix=''):
@@ -298,7 +308,6 @@ def expect_compile_error_helper(
error_message = e.error_message
error_message_lines = error_message.splitlines()
- error_message_lines = error_message.splitlines()
error_message_head = _cap_to_lines(error_message, 40)
check_error_fun(e, error_message_lines, error_message_head)
diff --git a/tests/test_common.cpp b/tests/test_common.cpp
new file mode 100644
index 0000000..868827f
--- /dev/null
+++ b/tests/test_common.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define IN_FRUIT_CPP_FILE 1
+
+#include "test_common.h"
+
+#include <fruit/impl/data_structures/semistatic_graph.templates.h>
+
+// Clang requires the following instantiation to be in its namespace.
+namespace fruit {
+namespace impl {
+
+template class SemistaticGraph<int, const char*>;
+template SemistaticGraph<int, char const*>::SemistaticGraph(std::vector<SimpleNode>::iterator first, std::vector<SimpleNode>::iterator last, MemoryPool& memory_pool);
+template SemistaticGraph<int, char const*>::SemistaticGraph(const fruit::impl::SemistaticGraph<int, char const*>& graph, std::vector<SimpleNode>::iterator first, std::vector<SimpleNode>::iterator last, MemoryPool& memory_pool);
+template class SemistaticMap<int, SemistaticGraphInternalNodeId>;
+
+} // namespace impl
+} // namespace fruit
+
+
+
diff --git a/tests/test_common.h b/tests/test_common.h
index d48f110..56e2b13 100644
--- a/tests/test_common.h
+++ b/tests/test_common.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef FRUIT_TEST_COMMON_H
-#define FRUIT_TEST_COMMON_H
+#ifndef FRUIT_COMMON_H
+#define FRUIT_COMMON_H
// This file includes headers used in various tests.
// This allows to improve compilation speed (and therefore test time) by pre-compiling this header.
@@ -27,4 +27,23 @@
#include <map>
#include <vector>
-#endif // FRUIT_TEST_COMMON_H
+// These are here because including Boost in test code would require depending on its headers but those files don't have
+// public visibility in the bazel repo.
+#include <fruit/impl/data_structures/semistatic_graph.h>
+using Graph = fruit::impl::SemistaticGraph<int, const char*>;
+using node_iterator = Graph::node_iterator;
+using edge_iterator = Graph::edge_iterator;
+struct SimpleNode {
+ int id;
+ const char* value;
+ const std::vector<int>* neighbors;
+ bool is_terminal;
+
+ int getId() { return id; }
+ const char* getValue() { return value; }
+ bool isTerminal() { return is_terminal; }
+ std::vector<int>::const_iterator getEdgesBegin() { return neighbors->begin(); }
+ std::vector<int>::const_iterator getEdgesEnd() { return neighbors->end(); }
+};
+
+#endif // FRUIT_COMMON_H
diff --git a/tests/test_component_functions.py b/tests/test_component_functions.py
index ec70bfc..8dc6a76 100755
--- a/tests/test_component_functions.py
+++ b/tests/test_component_functions.py
@@ -187,7 +187,8 @@ class TestComponentFunctions(parameterized.TestCase):
r'error: use of deleted function .Arg::Arg\(Arg&&\).'
r'|error: call to deleted constructor of .Arg.'
r'|.Arg::Arg\(Arg &&\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .int.'
- r'|error: copying parameter of type .Arg. invokes deleted constructor',
+ r'|error: copying parameter of type .Arg. invokes deleted constructor'
+ r'|error C2280: .Arg::Arg\(Arg &&\).: attempting to reference a deleted function',
COMMON_DEFINITIONS,
source)
diff --git a/tests/test_normalized_component.py b/tests/test_normalized_component.py
index ba21242..8888019 100755
--- a/tests/test_normalized_component.py
+++ b/tests/test_normalized_component.py
@@ -175,7 +175,7 @@ class TestNormalizedComponent(parameterized.TestCase):
expect_generic_compile_error(
r'no matching function for call to .fruit::NormalizedComponent<ConstXAnnot>::NormalizedComponent\(fruit::Component<XAnnot> \(&\)\(\)\).'
r'|no matching constructor for initialization of .fruit::NormalizedComponent<ConstXAnnot>.'
- r'|.fruit::NormalizedComponent<ConstXAnnot>::NormalizedComponent.: none of the 2 overloads could convert all the argument types',
+ r'|.fruit::NormalizedComponent<ConstXAnnot>::NormalizedComponent.: none of the .* overloads could convert all the argument types',
COMMON_DEFINITIONS,
source,
locals())
diff --git a/tests/test_register_constructor.py b/tests/test_register_constructor.py
index 4e2a4fc..b78191f 100755
--- a/tests/test_register_constructor.py
+++ b/tests/test_register_constructor.py
@@ -178,6 +178,10 @@ class TestRegisterConstructor(parameterized.TestCase):
source)
def test_register_constructor_error_abstract_class(self):
+ if re.search('MSVC', CXX_COMPILER_NAME) is not None:
+ # MSVC allows to construct the type X(int*) but SignatureType<Type<X(int*)>> doesn't find the
+ # specialization.
+ return
source = '''
struct X {
X(int*) {}
@@ -190,7 +194,7 @@ class TestRegisterConstructor(parameterized.TestCase):
.registerConstructor<fruit::Annotated<Annotation1, X>(int*)>();
}
'''
- if re.search('GNU|MSVC', CXX_COMPILER_NAME) is not None:
+ if re.search('GNU', CXX_COMPILER_NAME) is not None:
expect_generic_compile_error(
'invalid abstract return type'
'|.X.: cannot instantiate abstract class',
@@ -583,5 +587,46 @@ class TestRegisterConstructor(parameterized.TestCase):
source,
locals())
+ def test_register_constructor_error_assisted_param(self):
+ source = '''
+ struct X {
+ INJECT(X(ASSISTED(double) factor)) {
+ (void) factor;
+ }
+ };
+
+ fruit::Component<X> getComponent() {
+ return fruit::createComponent()
+ .registerConstructor<X(fruit::Assisted<double>)>();
+ }
+ '''
+ expect_compile_error(
+ 'AssistedParamInRegisterConstructorSignatureError<X\\(fruit::Assisted<double>\\)>',
+ 'CandidateSignature was used as signature for a registerConstructor.* but it contains an assisted parameter.',
+ COMMON_DEFINITIONS,
+ source,
+ locals())
+
+ def test_implicit_register_constructor_error_assisted_param(self):
+ source = '''
+ struct X {
+ INJECT(X(ASSISTED(double) factor)) {
+ (void) factor;
+ }
+ };
+
+ fruit::Component<X> getComponent() {
+ return fruit::createComponent();
+ }
+ '''
+ expect_compile_error(
+ 'AssistedParamInRegisterConstructorSignatureError<X\\(fruit::Assisted<double>\\)>',
+ 'CandidateSignature was used as signature for a registerConstructor.* but it contains an assisted parameter.',
+ COMMON_DEFINITIONS,
+ source,
+ locals())
+
+
+
if __name__ == '__main__':
absltest.main()
diff --git a/tests/test_register_factory.py b/tests/test_register_factory.py
index 202d18b..8f62946 100755
--- a/tests/test_register_factory.py
+++ b/tests/test_register_factory.py
@@ -2005,6 +2005,79 @@ class TestRegisterFactory(parameterized.TestCase):
source,
locals())
+ @multiple_parameters([
+ ('X()', 'X'),
+ ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
+ ], [
+ 'WithNoAnnotation',
+ 'WithAnnotation1',
+ ])
+ def test_register_factory_with_non_assignable_injected_param_success(self, ConstructX, XPtr, WithAnnot):
+ source = '''
+ struct Y {
+ Y(const Y&) = delete;
+ Y& operator=(const Y&) = delete;
+
+ Y() = default;
+ Y(Y&&) = default;
+ Y& operator=(Y&&) = default;
+ };
+ struct X {};
+
+ fruit::Component<WithAnnot<Y>> getYComponent() {
+ return fruit::createComponent()
+ .registerConstructor<WithAnnot<Y>()>();
+ }
+
+ fruit::Component<std::function<XPtr()>> getComponent() {
+ return fruit::createComponent()
+ .install(getYComponent)
+ .registerFactory<XPtr(WithAnnot<Y&>)>([](Y&){ return ConstructX; });
+ }
+
+ int main() {
+ fruit::Injector<std::function<XPtr()>> injector(getComponent);
+ XPtr x = injector.get<std::function<XPtr()>>()();
+ (void) x;
+ }
+ '''
+ expect_success(
+ COMMON_DEFINITIONS,
+ source,
+ locals())
+
+ @multiple_parameters([
+ ('X()', 'X'),
+ ('std::unique_ptr<X>(new X())', 'std::unique_ptr<X>'),
+ ])
+ def test_register_factory_with_non_assignable_assisted_param_success(self, ConstructX, XPtr):
+ source = '''
+ struct Y {
+ Y(const Y&) = delete;
+ Y& operator=(const Y&) = delete;
+
+ Y() = default;
+ Y(Y&&) = default;
+ Y& operator=(Y&&) = default;
+ };
+ struct X {};
+
+ fruit::Component<std::function<XPtr(Y)>> getComponent() {
+ return fruit::createComponent()
+ .registerFactory<XPtr(fruit::Assisted<Y>)>([](Y){ return ConstructX; });
+ }
+
+ int main() {
+ fruit::Injector<std::function<XPtr(Y)>> injector(getComponent);
+ XPtr x = injector.get<std::function<XPtr(Y)>>()(Y());
+ (void) x;
+ }
+ '''
+ expect_success(
+ COMMON_DEFINITIONS,
+ source,
+ locals())
+
def test_register_factory_requiring_nonconst_then_requiring_const_ok(self):
source = '''
struct X {};
diff --git a/tests/util/test_type_info.py b/tests/util/test_type_info.py
index b67f197..d433d60 100644
--- a/tests/util/test_type_info.py
+++ b/tests/util/test_type_info.py
@@ -51,7 +51,7 @@ class TestTypeInfo(parameterized.TestCase):
@parameterized.parameters([
('MyStruct', '{"MyStruct", "struct MyStruct"}'),
- ('std::pair<MyStruct, int>', '{"std::pair<MyStruct, int>", "std::__1::pair<MyStruct, int>"}'),
+ ('std::pair<MyStruct, int>', '{"std::pair<MyStruct, int>", "std::__1::pair<MyStruct, int>", "struct std::pair<struct MyStruct,int>"}'),
])
def test_name(self, T, Expected):
source = '''