From 73e9265f954528b6b2eccf98572e77126539a8df Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 23 Dec 2020 13:36:55 +0100 Subject: chore(3p/immer): Remove vendored copy of immer We ended up dropping the use of this library again. Change-Id: I2c44cd22a6128d23f87a582402bf5fb84991d608 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2292 Tested-by: BuildkiteCI Reviewed-by: Profpatsch --- third_party/immer/.clang-format | 38 - third_party/immer/.dir-locals.el | 7 - third_party/immer/.github/FUNDING.yml | 3 - third_party/immer/.gitignore | 24 - third_party/immer/.skip-subtree | 1 - third_party/immer/.travis.yml | 84 - third_party/immer/BUILD | 11 - third_party/immer/CMakeLists.txt | 141 - third_party/immer/LICENSE | 23 - third_party/immer/README.rst | 225 - third_party/immer/WORKSPACE | 0 third_party/immer/benchmark/CMakeLists.txt | 128 - third_party/immer/benchmark/config.hpp | 55 - third_party/immer/benchmark/extra/refcounting.cpp | 146 - third_party/immer/benchmark/set/access.hpp | 175 - third_party/immer/benchmark/set/access.ipp | 30 - third_party/immer/benchmark/set/insert.hpp | 55 - third_party/immer/benchmark/set/insert.ipp | 28 - third_party/immer/benchmark/set/iter.hpp | 111 - third_party/immer/benchmark/set/iter.ipp | 25 - .../immer/benchmark/set/string-box/access.cpp | 10 - .../immer/benchmark/set/string-box/generator.ipp | 46 - .../immer/benchmark/set/string-box/insert.cpp | 11 - .../immer/benchmark/set/string-box/iter.cpp | 10 - .../immer/benchmark/set/string-long/access.cpp | 10 - .../immer/benchmark/set/string-long/generator.ipp | 44 - .../immer/benchmark/set/string-long/insert.cpp | 11 - .../immer/benchmark/set/string-long/iter.cpp | 10 - .../immer/benchmark/set/string-short/access.cpp | 10 - .../immer/benchmark/set/string-short/generator.ipp | 44 - .../immer/benchmark/set/string-short/insert.cpp | 10 - .../immer/benchmark/set/string-short/iter.cpp | 10 - .../immer/benchmark/set/unsigned/access.cpp | 10 - .../immer/benchmark/set/unsigned/generator.ipp | 32 - .../immer/benchmark/set/unsigned/insert.cpp | 10 - third_party/immer/benchmark/set/unsigned/iter.cpp | 10 - third_party/immer/benchmark/vector/access.hpp | 261 - third_party/immer/benchmark/vector/assoc.hpp | 245 - .../immer/benchmark/vector/branching/access.ipp | 20 - .../immer/benchmark/vector/branching/assoc.ipp | 20 - .../benchmark/vector/branching/basic/access.cpp | 10 - .../benchmark/vector/branching/basic/assoc.cpp | 10 - .../benchmark/vector/branching/basic/concat.cpp | 10 - .../benchmark/vector/branching/basic/push.cpp | 10 - .../immer/benchmark/vector/branching/concat.ipp | 20 - .../immer/benchmark/vector/branching/gc/access.cpp | 10 - .../immer/benchmark/vector/branching/gc/assoc.cpp | 10 - .../immer/benchmark/vector/branching/gc/concat.cpp | 10 - .../immer/benchmark/vector/branching/gc/push.cpp | 10 - .../immer/benchmark/vector/branching/push.ipp | 20 - .../benchmark/vector/branching/safe/access.cpp | 10 - .../benchmark/vector/branching/safe/assoc.cpp | 10 - .../benchmark/vector/branching/safe/concat.cpp | 10 - .../immer/benchmark/vector/branching/safe/push.cpp | 10 - .../benchmark/vector/branching/unsafe/access.cpp | 10 - .../benchmark/vector/branching/unsafe/assoc.cpp | 10 - .../benchmark/vector/branching/unsafe/concat.cpp | 10 - .../benchmark/vector/branching/unsafe/push.cpp | 10 - third_party/immer/benchmark/vector/common.hpp | 212 - third_party/immer/benchmark/vector/concat.hpp | 166 - third_party/immer/benchmark/vector/drop.hpp | 142 - third_party/immer/benchmark/vector/misc/access.cpp | 94 - third_party/immer/benchmark/vector/misc/assoc.cpp | 119 - third_party/immer/benchmark/vector/misc/concat.cpp | 49 - third_party/immer/benchmark/vector/misc/drop.cpp | 63 - .../immer/benchmark/vector/misc/push-front.cpp | 30 - third_party/immer/benchmark/vector/misc/push.cpp | 83 - third_party/immer/benchmark/vector/misc/take.cpp | 65 - .../immer/benchmark/vector/paper/access.cpp | 31 - .../immer/benchmark/vector/paper/assoc-random.cpp | 40 - third_party/immer/benchmark/vector/paper/assoc.cpp | 40 - .../immer/benchmark/vector/paper/concat.cpp | 22 - third_party/immer/benchmark/vector/paper/push.cpp | 28 - third_party/immer/benchmark/vector/push.hpp | 111 - third_party/immer/benchmark/vector/push_front.hpp | 46 - third_party/immer/benchmark/vector/take.hpp | 144 - third_party/immer/cmake/FindBoehmGC.cmake | 108 - third_party/immer/cmake/FindGuile.cmake | 326 - third_party/immer/cmake/FindRRB.cmake | 15 - third_party/immer/cmake/ImmerUtils.cmake | 24 - third_party/immer/codecov.yml | 2 - third_party/immer/default.nix | 14 - third_party/immer/doc/CMakeLists.txt | 23 - third_party/immer/doc/Makefile | 226 - third_party/immer/doc/_static/logo-black.svg | 100 - third_party/immer/doc/_static/logo-front.svg | 99 - third_party/immer/doc/_static/logo.svg | 99 - third_party/immer/doc/_static/patreon.svg | 120 - third_party/immer/doc/_static/sinusoidal-badge.svg | 166 - third_party/immer/doc/algorithms.rst | 28 - third_party/immer/doc/conf.py | 452 - third_party/immer/doc/containers.rst | 50 - third_party/immer/doc/design.rst | 268 - third_party/immer/doc/doxygen.config | 23 - third_party/immer/doc/guile.rst | 1 - third_party/immer/doc/implementation.rst | 6 - third_party/immer/doc/index.rst | 31 - third_party/immer/doc/introduction.rst | 6 - third_party/immer/doc/memory.rst | 204 - third_party/immer/doc/python.rst | 1 - third_party/immer/doc/requirements.txt | 3 - third_party/immer/doc/sphinx-html-hack.bash | 101 - third_party/immer/doc/transients.rst | 51 - third_party/immer/doc/utilities.rst | 15 - third_party/immer/example/CMakeLists.txt | 17 - third_party/immer/example/array/array.cpp | 54 - third_party/immer/example/box/box.cpp | 25 - .../immer/example/flex-vector/flex-vector.cpp | 103 - third_party/immer/example/map/intro.cpp | 23 - third_party/immer/example/set/intro.cpp | 22 - third_party/immer/example/vector/fizzbuzz.cpp | 34 - third_party/immer/example/vector/gc.cpp | 37 - third_party/immer/example/vector/intro.cpp | 22 - third_party/immer/example/vector/iota-move.cpp | 25 - third_party/immer/example/vector/iota-slow.cpp | 25 - .../immer/example/vector/iota-transient-std.cpp | 29 - .../immer/example/vector/iota-transient.cpp | 27 - third_party/immer/example/vector/move.cpp | 35 - third_party/immer/example/vector/vector.cpp | 53 - third_party/immer/extra/fuzzer/CMakeLists.txt | 29 - third_party/immer/extra/fuzzer/array-gc.cpp | 103 - third_party/immer/extra/fuzzer/array.cpp | 80 - third_party/immer/extra/fuzzer/flex-vector-gc.cpp | 162 - third_party/immer/extra/fuzzer/flex-vector.cpp | 150 - third_party/immer/extra/fuzzer/fuzzer_input.hpp | 62 - third_party/immer/extra/fuzzer/map-gc.cpp | 93 - third_party/immer/extra/fuzzer/map.cpp | 85 - third_party/immer/extra/fuzzer/set-gc.cpp | 78 - third_party/immer/extra/fuzzer/set.cpp | 70 - third_party/immer/extra/fuzzer/vector-gc.cpp | 104 - third_party/immer/extra/fuzzer/vector.cpp | 82 - third_party/immer/extra/guile/CMakeLists.txt | 24 - third_party/immer/extra/guile/README.rst | 144 - third_party/immer/extra/guile/benchmark.scm | 168 - third_party/immer/extra/guile/example.scm | 51 - third_party/immer/extra/guile/immer.scm.in | 5 - .../immer/extra/guile/scm/detail/convert.hpp | 58 - .../immer/extra/guile/scm/detail/define.hpp | 36 - .../extra/guile/scm/detail/finalizer_wrapper.hpp | 62 - .../immer/extra/guile/scm/detail/function_args.hpp | 21 - .../immer/extra/guile/scm/detail/invoke.hpp | 39 - third_party/immer/extra/guile/scm/detail/pack.hpp | 52 - .../immer/extra/guile/scm/detail/subr_wrapper.hpp | 111 - third_party/immer/extra/guile/scm/detail/util.hpp | 49 - third_party/immer/extra/guile/scm/group.hpp | 88 - third_party/immer/extra/guile/scm/list.hpp | 54 - third_party/immer/extra/guile/scm/scm.hpp | 14 - third_party/immer/extra/guile/scm/type.hpp | 153 - third_party/immer/extra/guile/scm/val.hpp | 88 - third_party/immer/extra/guile/src/immer.cpp | 153 - third_party/immer/extra/js/immer.cpp | 79 - third_party/immer/extra/js/index.js | 74 - third_party/immer/extra/js/index.tpl.html | 77 - third_party/immer/extra/js/lib/benchmark.js | 2811 ---- third_party/immer/extra/js/lib/immutable.min.js | 36 - third_party/immer/extra/js/lib/lodash.js | 16607 ------------------- third_party/immer/extra/js/lib/mori.js | 435 - third_party/immer/extra/js/lib/platform.js | 1135 -- third_party/immer/extra/js/makefile | 29 - third_party/immer/extra/python/CMakeLists.txt | 46 - third_party/immer/extra/python/README.rst | 42 - .../extra/python/benchmark/test_benchmarks.py | 45 - third_party/immer/extra/python/example.py | 21 - third_party/immer/extra/python/immer/__init__.py | 2 - third_party/immer/extra/python/lib/pybind11 | 1 - third_party/immer/extra/python/src/immer-boost.cpp | 80 - .../immer/extra/python/src/immer-pybind.cpp | 77 - third_party/immer/extra/python/src/immer-raw.cpp | 402 - third_party/immer/immer/algorithm.hpp | 212 - third_party/immer/immer/array.hpp | 364 - third_party/immer/immer/array_transient.hpp | 202 - third_party/immer/immer/atom.hpp | 254 - third_party/immer/immer/box.hpp | 194 - third_party/immer/immer/config.hpp | 93 - .../immer/immer/detail/arrays/no_capacity.hpp | 203 - third_party/immer/immer/detail/arrays/node.hpp | 127 - .../immer/immer/detail/arrays/with_capacity.hpp | 303 - .../immer/immer/detail/combine_standard_layout.hpp | 235 - third_party/immer/immer/detail/hamts/bits.hpp | 108 - third_party/immer/immer/detail/hamts/champ.hpp | 473 - .../immer/immer/detail/hamts/champ_iterator.hpp | 148 - third_party/immer/immer/detail/hamts/node.hpp | 717 - third_party/immer/immer/detail/iterator_facade.hpp | 212 - third_party/immer/immer/detail/rbts/bits.hpp | 33 - third_party/immer/immer/detail/rbts/node.hpp | 932 -- third_party/immer/immer/detail/rbts/operations.hpp | 2461 --- third_party/immer/immer/detail/rbts/position.hpp | 1977 --- third_party/immer/immer/detail/rbts/rbtree.hpp | 509 - .../immer/immer/detail/rbts/rbtree_iterator.hpp | 99 - third_party/immer/immer/detail/rbts/rrbtree.hpp | 1396 -- .../immer/immer/detail/rbts/rrbtree_iterator.hpp | 98 - third_party/immer/immer/detail/rbts/visitor.hpp | 56 - third_party/immer/immer/detail/ref_count_base.hpp | 36 - third_party/immer/immer/detail/type_traits.hpp | 223 - third_party/immer/immer/detail/util.hpp | 258 - .../immer/experimental/detail/dvektor_impl.hpp | 498 - third_party/immer/immer/experimental/dvektor.hpp | 69 - third_party/immer/immer/flex_vector.hpp | 608 - third_party/immer/immer/flex_vector_transient.hpp | 251 - third_party/immer/immer/heap/cpp_heap.hpp | 41 - third_party/immer/immer/heap/debug_size_heap.hpp | 69 - third_party/immer/immer/heap/free_list_heap.hpp | 83 - third_party/immer/immer/heap/free_list_node.hpp | 24 - third_party/immer/immer/heap/gc_heap.hpp | 127 - third_party/immer/immer/heap/heap_policy.hpp | 141 - third_party/immer/immer/heap/identity_heap.hpp | 34 - third_party/immer/immer/heap/malloc_heap.hpp | 44 - third_party/immer/immer/heap/split_heap.hpp | 40 - third_party/immer/immer/heap/tags.hpp | 16 - .../immer/heap/thread_local_free_list_heap.hpp | 55 - .../immer/immer/heap/unsafe_free_list_heap.hpp | 109 - third_party/immer/immer/heap/with_data.hpp | 43 - third_party/immer/immer/map.hpp | 342 - third_party/immer/immer/map_transient.hpp | 41 - third_party/immer/immer/memory_policy.hpp | 135 - .../immer/immer/refcount/enable_intrusive_ptr.hpp | 37 - .../immer/immer/refcount/no_refcount_policy.hpp | 45 - .../immer/immer/refcount/refcount_policy.hpp | 101 - .../immer/refcount/unsafe_refcount_policy.hpp | 40 - third_party/immer/immer/set.hpp | 198 - third_party/immer/immer/set_transient.hpp | 40 - .../immer/transience/gc_transience_policy.hpp | 110 - .../immer/transience/no_transience_policy.hpp | 48 - third_party/immer/immer/vector.hpp | 412 - third_party/immer/immer/vector_transient.hpp | 203 - third_party/immer/nix/benchmarks.nix | 100 - third_party/immer/nix/docs.nix | 27 - third_party/immer/setup.py | 68 - third_party/immer/shell.nix | 65 - third_party/immer/test/CMakeLists.txt | 22 - third_party/immer/test/array/default.cpp | 12 - third_party/immer/test/array/gc.cpp | 22 - third_party/immer/test/array_transient/default.cpp | 41 - third_party/immer/test/array_transient/gc.cpp | 50 - third_party/immer/test/atom/default.cpp | 12 - third_party/immer/test/atom/gc.cpp | 20 - third_party/immer/test/atom/generic.ipp | 53 - third_party/immer/test/box/default.cpp | 12 - third_party/immer/test/box/gc.cpp | 20 - third_party/immer/test/box/generic.ipp | 58 - third_party/immer/test/box/recursive.cpp | 108 - .../immer/test/box/vector-of-boxes-transient.cpp | 36 - third_party/immer/test/dada.hpp | 243 - third_party/immer/test/detail/type_traits.cpp | 215 - third_party/immer/test/experimental/dvektor.cpp | 198 - third_party/immer/test/flex_vector/B3-BL0.cpp | 21 - third_party/immer/test/flex_vector/B3-BL3.cpp | 21 - third_party/immer/test/flex_vector/default.cpp | 14 - third_party/immer/test/flex_vector/fuzzed-0.cpp | 380 - third_party/immer/test/flex_vector/fuzzed-1.cpp | 368 - third_party/immer/test/flex_vector/fuzzed-2.cpp | 188 - third_party/immer/test/flex_vector/fuzzed-3.cpp | 222 - third_party/immer/test/flex_vector/fuzzed-4.cpp | 364 - third_party/immer/test/flex_vector/gc.cpp | 27 - third_party/immer/test/flex_vector/generic.ipp | 599 - third_party/immer/test/flex_vector/issue-45.cpp | 35 - third_party/immer/test/flex_vector/issue-47.cpp | 5 - .../immer/test/flex_vector/regular-B3-BL3.cpp | 16 - .../immer/test/flex_vector/regular-default.cpp | 12 - .../immer/test/flex_vector_transient/B3-BL0.cpp | 29 - .../immer/test/flex_vector_transient/default.cpp | 17 - .../immer/test/flex_vector_transient/gc.cpp | 34 - .../immer/test/flex_vector_transient/generic.ipp | 398 - .../test/flex_vector_transient/regular-default.cpp | 15 - .../test/flex_vector_transient/regular-gc.cpp | 31 - third_party/immer/test/map/B3.cpp | 18 - third_party/immer/test/map/B6.cpp | 18 - third_party/immer/test/map/default.cpp | 12 - third_party/immer/test/map/gc.cpp | 25 - third_party/immer/test/map/generic.ipp | 312 - third_party/immer/test/map/issue-56.cpp | 42 - third_party/immer/test/memory/heaps.cpp | 101 - third_party/immer/test/memory/refcounts.cpp | 62 - third_party/immer/test/set/B3.cpp | 17 - third_party/immer/test/set/B6.cpp | 17 - third_party/immer/test/set/default.cpp | 12 - third_party/immer/test/set/gc.cpp | 24 - third_party/immer/test/set/generic.ipp | 459 - third_party/immer/test/transient_tester.hpp | 54 - third_party/immer/test/util.hpp | 103 - third_party/immer/test/vector/B3-BL0.cpp | 15 - third_party/immer/test/vector/B3-BL2.cpp | 15 - third_party/immer/test/vector/B3-BL3.cpp | 15 - third_party/immer/test/vector/B3-BL4.cpp | 15 - third_party/immer/test/vector/default.cpp | 12 - third_party/immer/test/vector/gc.cpp | 22 - third_party/immer/test/vector/generic.ipp | 488 - third_party/immer/test/vector/issue-16.cpp | 122 - third_party/immer/test/vector/issue-46.cpp | 39 - third_party/immer/test/vector/issue-74.cpp | 24 - third_party/immer/test/vector_transient/B3-BL0.cpp | 21 - .../immer/test/vector_transient/default.cpp | 15 - third_party/immer/test/vector_transient/gc.cpp | 29 - .../immer/test/vector_transient/generic.ipp | 267 - third_party/immer/tools/clojure/README.md | 4 - third_party/immer/tools/clojure/project.clj | 12 - .../immer/tools/clojure/src/immer_benchmark.clj | 131 - third_party/immer/tools/docker/icfp17/Dockerfile | 77 - third_party/immer/tools/include/catch.hpp | 9458 ----------- third_party/immer/tools/include/doctest.h | 5696 ------- third_party/immer/tools/include/nonius.h++ | 4292 ----- third_party/immer/tools/include/prettyprint.hpp | 445 - .../immer/tools/reproduce-paper-results.bash | 25 - third_party/immer/tools/scala/README.md | 6 - third_party/immer/tools/scala/build.sbt | 27 - .../src/test/scala/org/immer/benchmarks.scala | 168 - third_party/immer/tools/scala/version.sbt | 1 - third_party/immer/tools/sinusoidal-sphinx-theme | 1 - third_party/immer/tools/travis/ssh-key.enc | Bin 1680 -> 0 bytes third_party/immer/tools/travis/ssh-key.pub | 1 - third_party/immer/tools/with-tee.bash | 5 - 311 files changed, 74218 deletions(-) delete mode 100644 third_party/immer/.clang-format delete mode 100644 third_party/immer/.dir-locals.el delete mode 100644 third_party/immer/.github/FUNDING.yml delete mode 100644 third_party/immer/.gitignore delete mode 100644 third_party/immer/.skip-subtree delete mode 100644 third_party/immer/.travis.yml delete mode 100644 third_party/immer/BUILD delete mode 100644 third_party/immer/CMakeLists.txt delete mode 100644 third_party/immer/LICENSE delete mode 100644 third_party/immer/README.rst delete mode 100644 third_party/immer/WORKSPACE delete mode 100644 third_party/immer/benchmark/CMakeLists.txt delete mode 100644 third_party/immer/benchmark/config.hpp delete mode 100644 third_party/immer/benchmark/extra/refcounting.cpp delete mode 100644 third_party/immer/benchmark/set/access.hpp delete mode 100644 third_party/immer/benchmark/set/access.ipp delete mode 100644 third_party/immer/benchmark/set/insert.hpp delete mode 100644 third_party/immer/benchmark/set/insert.ipp delete mode 100644 third_party/immer/benchmark/set/iter.hpp delete mode 100644 third_party/immer/benchmark/set/iter.ipp delete mode 100644 third_party/immer/benchmark/set/string-box/access.cpp delete mode 100644 third_party/immer/benchmark/set/string-box/generator.ipp delete mode 100644 third_party/immer/benchmark/set/string-box/insert.cpp delete mode 100644 third_party/immer/benchmark/set/string-box/iter.cpp delete mode 100644 third_party/immer/benchmark/set/string-long/access.cpp delete mode 100644 third_party/immer/benchmark/set/string-long/generator.ipp delete mode 100644 third_party/immer/benchmark/set/string-long/insert.cpp delete mode 100644 third_party/immer/benchmark/set/string-long/iter.cpp delete mode 100644 third_party/immer/benchmark/set/string-short/access.cpp delete mode 100644 third_party/immer/benchmark/set/string-short/generator.ipp delete mode 100644 third_party/immer/benchmark/set/string-short/insert.cpp delete mode 100644 third_party/immer/benchmark/set/string-short/iter.cpp delete mode 100644 third_party/immer/benchmark/set/unsigned/access.cpp delete mode 100644 third_party/immer/benchmark/set/unsigned/generator.ipp delete mode 100644 third_party/immer/benchmark/set/unsigned/insert.cpp delete mode 100644 third_party/immer/benchmark/set/unsigned/iter.cpp delete mode 100644 third_party/immer/benchmark/vector/access.hpp delete mode 100644 third_party/immer/benchmark/vector/assoc.hpp delete mode 100644 third_party/immer/benchmark/vector/branching/access.ipp delete mode 100644 third_party/immer/benchmark/vector/branching/assoc.ipp delete mode 100644 third_party/immer/benchmark/vector/branching/basic/access.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/basic/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/basic/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/basic/push.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/concat.ipp delete mode 100644 third_party/immer/benchmark/vector/branching/gc/access.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/gc/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/gc/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/gc/push.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/push.ipp delete mode 100644 third_party/immer/benchmark/vector/branching/safe/access.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/safe/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/safe/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/safe/push.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/unsafe/access.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/unsafe/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/branching/unsafe/push.cpp delete mode 100644 third_party/immer/benchmark/vector/common.hpp delete mode 100644 third_party/immer/benchmark/vector/concat.hpp delete mode 100644 third_party/immer/benchmark/vector/drop.hpp delete mode 100644 third_party/immer/benchmark/vector/misc/access.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/drop.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/push-front.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/push.cpp delete mode 100644 third_party/immer/benchmark/vector/misc/take.cpp delete mode 100644 third_party/immer/benchmark/vector/paper/access.cpp delete mode 100644 third_party/immer/benchmark/vector/paper/assoc-random.cpp delete mode 100644 third_party/immer/benchmark/vector/paper/assoc.cpp delete mode 100644 third_party/immer/benchmark/vector/paper/concat.cpp delete mode 100644 third_party/immer/benchmark/vector/paper/push.cpp delete mode 100644 third_party/immer/benchmark/vector/push.hpp delete mode 100644 third_party/immer/benchmark/vector/push_front.hpp delete mode 100644 third_party/immer/benchmark/vector/take.hpp delete mode 100644 third_party/immer/cmake/FindBoehmGC.cmake delete mode 100644 third_party/immer/cmake/FindGuile.cmake delete mode 100644 third_party/immer/cmake/FindRRB.cmake delete mode 100644 third_party/immer/cmake/ImmerUtils.cmake delete mode 100644 third_party/immer/codecov.yml delete mode 100644 third_party/immer/default.nix delete mode 100644 third_party/immer/doc/CMakeLists.txt delete mode 100644 third_party/immer/doc/Makefile delete mode 100644 third_party/immer/doc/_static/logo-black.svg delete mode 100644 third_party/immer/doc/_static/logo-front.svg delete mode 100644 third_party/immer/doc/_static/logo.svg delete mode 100644 third_party/immer/doc/_static/patreon.svg delete mode 100644 third_party/immer/doc/_static/sinusoidal-badge.svg delete mode 100644 third_party/immer/doc/algorithms.rst delete mode 100644 third_party/immer/doc/conf.py delete mode 100644 third_party/immer/doc/containers.rst delete mode 100644 third_party/immer/doc/design.rst delete mode 100644 third_party/immer/doc/doxygen.config delete mode 120000 third_party/immer/doc/guile.rst delete mode 100644 third_party/immer/doc/implementation.rst delete mode 100644 third_party/immer/doc/index.rst delete mode 100644 third_party/immer/doc/introduction.rst delete mode 100644 third_party/immer/doc/memory.rst delete mode 120000 third_party/immer/doc/python.rst delete mode 100644 third_party/immer/doc/requirements.txt delete mode 100755 third_party/immer/doc/sphinx-html-hack.bash delete mode 100644 third_party/immer/doc/transients.rst delete mode 100644 third_party/immer/doc/utilities.rst delete mode 100644 third_party/immer/example/CMakeLists.txt delete mode 100644 third_party/immer/example/array/array.cpp delete mode 100644 third_party/immer/example/box/box.cpp delete mode 100644 third_party/immer/example/flex-vector/flex-vector.cpp delete mode 100644 third_party/immer/example/map/intro.cpp delete mode 100644 third_party/immer/example/set/intro.cpp delete mode 100644 third_party/immer/example/vector/fizzbuzz.cpp delete mode 100644 third_party/immer/example/vector/gc.cpp delete mode 100644 third_party/immer/example/vector/intro.cpp delete mode 100644 third_party/immer/example/vector/iota-move.cpp delete mode 100644 third_party/immer/example/vector/iota-slow.cpp delete mode 100644 third_party/immer/example/vector/iota-transient-std.cpp delete mode 100644 third_party/immer/example/vector/iota-transient.cpp delete mode 100644 third_party/immer/example/vector/move.cpp delete mode 100644 third_party/immer/example/vector/vector.cpp delete mode 100644 third_party/immer/extra/fuzzer/CMakeLists.txt delete mode 100644 third_party/immer/extra/fuzzer/array-gc.cpp delete mode 100644 third_party/immer/extra/fuzzer/array.cpp delete mode 100644 third_party/immer/extra/fuzzer/flex-vector-gc.cpp delete mode 100644 third_party/immer/extra/fuzzer/flex-vector.cpp delete mode 100644 third_party/immer/extra/fuzzer/fuzzer_input.hpp delete mode 100644 third_party/immer/extra/fuzzer/map-gc.cpp delete mode 100644 third_party/immer/extra/fuzzer/map.cpp delete mode 100644 third_party/immer/extra/fuzzer/set-gc.cpp delete mode 100644 third_party/immer/extra/fuzzer/set.cpp delete mode 100644 third_party/immer/extra/fuzzer/vector-gc.cpp delete mode 100644 third_party/immer/extra/fuzzer/vector.cpp delete mode 100644 third_party/immer/extra/guile/CMakeLists.txt delete mode 100644 third_party/immer/extra/guile/README.rst delete mode 100644 third_party/immer/extra/guile/benchmark.scm delete mode 100644 third_party/immer/extra/guile/example.scm delete mode 100644 third_party/immer/extra/guile/immer.scm.in delete mode 100644 third_party/immer/extra/guile/scm/detail/convert.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/define.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/function_args.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/invoke.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/pack.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp delete mode 100644 third_party/immer/extra/guile/scm/detail/util.hpp delete mode 100644 third_party/immer/extra/guile/scm/group.hpp delete mode 100644 third_party/immer/extra/guile/scm/list.hpp delete mode 100644 third_party/immer/extra/guile/scm/scm.hpp delete mode 100644 third_party/immer/extra/guile/scm/type.hpp delete mode 100644 third_party/immer/extra/guile/scm/val.hpp delete mode 100644 third_party/immer/extra/guile/src/immer.cpp delete mode 100644 third_party/immer/extra/js/immer.cpp delete mode 100644 third_party/immer/extra/js/index.js delete mode 100644 third_party/immer/extra/js/index.tpl.html delete mode 100644 third_party/immer/extra/js/lib/benchmark.js delete mode 100644 third_party/immer/extra/js/lib/immutable.min.js delete mode 100644 third_party/immer/extra/js/lib/lodash.js delete mode 100644 third_party/immer/extra/js/lib/mori.js delete mode 100644 third_party/immer/extra/js/lib/platform.js delete mode 100644 third_party/immer/extra/js/makefile delete mode 100644 third_party/immer/extra/python/CMakeLists.txt delete mode 100644 third_party/immer/extra/python/README.rst delete mode 100644 third_party/immer/extra/python/benchmark/test_benchmarks.py delete mode 100755 third_party/immer/extra/python/example.py delete mode 100644 third_party/immer/extra/python/immer/__init__.py delete mode 160000 third_party/immer/extra/python/lib/pybind11 delete mode 100644 third_party/immer/extra/python/src/immer-boost.cpp delete mode 100644 third_party/immer/extra/python/src/immer-pybind.cpp delete mode 100644 third_party/immer/extra/python/src/immer-raw.cpp delete mode 100644 third_party/immer/immer/algorithm.hpp delete mode 100644 third_party/immer/immer/array.hpp delete mode 100644 third_party/immer/immer/array_transient.hpp delete mode 100644 third_party/immer/immer/atom.hpp delete mode 100644 third_party/immer/immer/box.hpp delete mode 100644 third_party/immer/immer/config.hpp delete mode 100644 third_party/immer/immer/detail/arrays/no_capacity.hpp delete mode 100644 third_party/immer/immer/detail/arrays/node.hpp delete mode 100644 third_party/immer/immer/detail/arrays/with_capacity.hpp delete mode 100644 third_party/immer/immer/detail/combine_standard_layout.hpp delete mode 100644 third_party/immer/immer/detail/hamts/bits.hpp delete mode 100644 third_party/immer/immer/detail/hamts/champ.hpp delete mode 100644 third_party/immer/immer/detail/hamts/champ_iterator.hpp delete mode 100644 third_party/immer/immer/detail/hamts/node.hpp delete mode 100644 third_party/immer/immer/detail/iterator_facade.hpp delete mode 100644 third_party/immer/immer/detail/rbts/bits.hpp delete mode 100644 third_party/immer/immer/detail/rbts/node.hpp delete mode 100644 third_party/immer/immer/detail/rbts/operations.hpp delete mode 100644 third_party/immer/immer/detail/rbts/position.hpp delete mode 100644 third_party/immer/immer/detail/rbts/rbtree.hpp delete mode 100644 third_party/immer/immer/detail/rbts/rbtree_iterator.hpp delete mode 100644 third_party/immer/immer/detail/rbts/rrbtree.hpp delete mode 100644 third_party/immer/immer/detail/rbts/rrbtree_iterator.hpp delete mode 100644 third_party/immer/immer/detail/rbts/visitor.hpp delete mode 100644 third_party/immer/immer/detail/ref_count_base.hpp delete mode 100644 third_party/immer/immer/detail/type_traits.hpp delete mode 100644 third_party/immer/immer/detail/util.hpp delete mode 100644 third_party/immer/immer/experimental/detail/dvektor_impl.hpp delete mode 100644 third_party/immer/immer/experimental/dvektor.hpp delete mode 100644 third_party/immer/immer/flex_vector.hpp delete mode 100644 third_party/immer/immer/flex_vector_transient.hpp delete mode 100644 third_party/immer/immer/heap/cpp_heap.hpp delete mode 100644 third_party/immer/immer/heap/debug_size_heap.hpp delete mode 100644 third_party/immer/immer/heap/free_list_heap.hpp delete mode 100644 third_party/immer/immer/heap/free_list_node.hpp delete mode 100644 third_party/immer/immer/heap/gc_heap.hpp delete mode 100644 third_party/immer/immer/heap/heap_policy.hpp delete mode 100644 third_party/immer/immer/heap/identity_heap.hpp delete mode 100644 third_party/immer/immer/heap/malloc_heap.hpp delete mode 100644 third_party/immer/immer/heap/split_heap.hpp delete mode 100644 third_party/immer/immer/heap/tags.hpp delete mode 100644 third_party/immer/immer/heap/thread_local_free_list_heap.hpp delete mode 100644 third_party/immer/immer/heap/unsafe_free_list_heap.hpp delete mode 100644 third_party/immer/immer/heap/with_data.hpp delete mode 100644 third_party/immer/immer/map.hpp delete mode 100644 third_party/immer/immer/map_transient.hpp delete mode 100644 third_party/immer/immer/memory_policy.hpp delete mode 100644 third_party/immer/immer/refcount/enable_intrusive_ptr.hpp delete mode 100644 third_party/immer/immer/refcount/no_refcount_policy.hpp delete mode 100644 third_party/immer/immer/refcount/refcount_policy.hpp delete mode 100644 third_party/immer/immer/refcount/unsafe_refcount_policy.hpp delete mode 100644 third_party/immer/immer/set.hpp delete mode 100644 third_party/immer/immer/set_transient.hpp delete mode 100644 third_party/immer/immer/transience/gc_transience_policy.hpp delete mode 100644 third_party/immer/immer/transience/no_transience_policy.hpp delete mode 100644 third_party/immer/immer/vector.hpp delete mode 100644 third_party/immer/immer/vector_transient.hpp delete mode 100644 third_party/immer/nix/benchmarks.nix delete mode 100644 third_party/immer/nix/docs.nix delete mode 100644 third_party/immer/setup.py delete mode 100644 third_party/immer/shell.nix delete mode 100644 third_party/immer/test/CMakeLists.txt delete mode 100644 third_party/immer/test/array/default.cpp delete mode 100644 third_party/immer/test/array/gc.cpp delete mode 100644 third_party/immer/test/array_transient/default.cpp delete mode 100644 third_party/immer/test/array_transient/gc.cpp delete mode 100644 third_party/immer/test/atom/default.cpp delete mode 100644 third_party/immer/test/atom/gc.cpp delete mode 100644 third_party/immer/test/atom/generic.ipp delete mode 100644 third_party/immer/test/box/default.cpp delete mode 100644 third_party/immer/test/box/gc.cpp delete mode 100644 third_party/immer/test/box/generic.ipp delete mode 100644 third_party/immer/test/box/recursive.cpp delete mode 100644 third_party/immer/test/box/vector-of-boxes-transient.cpp delete mode 100644 third_party/immer/test/dada.hpp delete mode 100644 third_party/immer/test/detail/type_traits.cpp delete mode 100644 third_party/immer/test/experimental/dvektor.cpp delete mode 100644 third_party/immer/test/flex_vector/B3-BL0.cpp delete mode 100644 third_party/immer/test/flex_vector/B3-BL3.cpp delete mode 100644 third_party/immer/test/flex_vector/default.cpp delete mode 100644 third_party/immer/test/flex_vector/fuzzed-0.cpp delete mode 100644 third_party/immer/test/flex_vector/fuzzed-1.cpp delete mode 100644 third_party/immer/test/flex_vector/fuzzed-2.cpp delete mode 100644 third_party/immer/test/flex_vector/fuzzed-3.cpp delete mode 100644 third_party/immer/test/flex_vector/fuzzed-4.cpp delete mode 100644 third_party/immer/test/flex_vector/gc.cpp delete mode 100644 third_party/immer/test/flex_vector/generic.ipp delete mode 100644 third_party/immer/test/flex_vector/issue-45.cpp delete mode 100644 third_party/immer/test/flex_vector/issue-47.cpp delete mode 100644 third_party/immer/test/flex_vector/regular-B3-BL3.cpp delete mode 100644 third_party/immer/test/flex_vector/regular-default.cpp delete mode 100644 third_party/immer/test/flex_vector_transient/B3-BL0.cpp delete mode 100644 third_party/immer/test/flex_vector_transient/default.cpp delete mode 100644 third_party/immer/test/flex_vector_transient/gc.cpp delete mode 100644 third_party/immer/test/flex_vector_transient/generic.ipp delete mode 100644 third_party/immer/test/flex_vector_transient/regular-default.cpp delete mode 100644 third_party/immer/test/flex_vector_transient/regular-gc.cpp delete mode 100644 third_party/immer/test/map/B3.cpp delete mode 100644 third_party/immer/test/map/B6.cpp delete mode 100644 third_party/immer/test/map/default.cpp delete mode 100644 third_party/immer/test/map/gc.cpp delete mode 100644 third_party/immer/test/map/generic.ipp delete mode 100644 third_party/immer/test/map/issue-56.cpp delete mode 100644 third_party/immer/test/memory/heaps.cpp delete mode 100644 third_party/immer/test/memory/refcounts.cpp delete mode 100644 third_party/immer/test/set/B3.cpp delete mode 100644 third_party/immer/test/set/B6.cpp delete mode 100644 third_party/immer/test/set/default.cpp delete mode 100644 third_party/immer/test/set/gc.cpp delete mode 100644 third_party/immer/test/set/generic.ipp delete mode 100644 third_party/immer/test/transient_tester.hpp delete mode 100644 third_party/immer/test/util.hpp delete mode 100644 third_party/immer/test/vector/B3-BL0.cpp delete mode 100644 third_party/immer/test/vector/B3-BL2.cpp delete mode 100644 third_party/immer/test/vector/B3-BL3.cpp delete mode 100644 third_party/immer/test/vector/B3-BL4.cpp delete mode 100644 third_party/immer/test/vector/default.cpp delete mode 100644 third_party/immer/test/vector/gc.cpp delete mode 100644 third_party/immer/test/vector/generic.ipp delete mode 100644 third_party/immer/test/vector/issue-16.cpp delete mode 100644 third_party/immer/test/vector/issue-46.cpp delete mode 100644 third_party/immer/test/vector/issue-74.cpp delete mode 100644 third_party/immer/test/vector_transient/B3-BL0.cpp delete mode 100644 third_party/immer/test/vector_transient/default.cpp delete mode 100644 third_party/immer/test/vector_transient/gc.cpp delete mode 100644 third_party/immer/test/vector_transient/generic.ipp delete mode 100644 third_party/immer/tools/clojure/README.md delete mode 100644 third_party/immer/tools/clojure/project.clj delete mode 100644 third_party/immer/tools/clojure/src/immer_benchmark.clj delete mode 100644 third_party/immer/tools/docker/icfp17/Dockerfile delete mode 100644 third_party/immer/tools/include/catch.hpp delete mode 100644 third_party/immer/tools/include/doctest.h delete mode 100644 third_party/immer/tools/include/nonius.h++ delete mode 100644 third_party/immer/tools/include/prettyprint.hpp delete mode 100755 third_party/immer/tools/reproduce-paper-results.bash delete mode 100644 third_party/immer/tools/scala/README.md delete mode 100644 third_party/immer/tools/scala/build.sbt delete mode 100644 third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala delete mode 100644 third_party/immer/tools/scala/version.sbt delete mode 160000 third_party/immer/tools/sinusoidal-sphinx-theme delete mode 100644 third_party/immer/tools/travis/ssh-key.enc delete mode 100644 third_party/immer/tools/travis/ssh-key.pub delete mode 100755 third_party/immer/tools/with-tee.bash diff --git a/third_party/immer/.clang-format b/third_party/immer/.clang-format deleted file mode 100644 index f7308d25886e..000000000000 --- a/third_party/immer/.clang-format +++ /dev/null @@ -1,38 +0,0 @@ ---- -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: 'true' -AlignEscapedNewlines: Right -AlignTrailingComments: 'true' -AllowShortFunctionsOnASingleLine: 'true' -AllowShortBlocksOnASingleLine: 'true' -AlwaysBreakTemplateDeclarations: 'true' -AccessModifierOffset: -4 -BinPackArguments: 'false' -BinPackParameters: 'false' -BreakBeforeBraces: Mozilla -BreakBeforeInheritanceComma: 'true' -BreakBeforeTernaryOperators: 'true' -BreakConstructorInitializers: BeforeComma -BreakStringLiterals: 'true' -ColumnLimit: '80' -CompactNamespaces: 'false' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'false' -FixNamespaceComments: 'true' -IndentCaseLabels: 'false' -IndentWidth: '4' -IndentWrappedFunctionNames: 'false' -KeepEmptyLinesAtTheStartOfBlocks: 'false' -Language: Cpp -MaxEmptyLinesToKeep: '1' -NamespaceIndentation: None -PointerAlignment: Left -ReflowComments: 'true' -SortIncludes: 'true' -SortUsingDeclarations: 'true' -SpaceAfterCStyleCast: 'true' -SpaceAfterTemplateKeyword: 'true' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeParens: ControlStatements -TabWidth: '4' -UseTab: Never -... diff --git a/third_party/immer/.dir-locals.el b/third_party/immer/.dir-locals.el deleted file mode 100644 index 8adc4f1d2032..000000000000 --- a/third_party/immer/.dir-locals.el +++ /dev/null @@ -1,7 +0,0 @@ -((nil . - ((indent-tabs-mode . nil) - (show-trailing-whitespace . t))) - (c-mode . - ((mode . c++))) - (c++-mode . - ((eval add-hook 'before-save-hook #'clang-format-buffer nil t)))) diff --git a/third_party/immer/.github/FUNDING.yml b/third_party/immer/.github/FUNDING.yml deleted file mode 100644 index defc6ca1fa1d..000000000000 --- a/third_party/immer/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -github: arximboldi -patreon: sinusoidal -custom: ["paypal.me/sinusoidal", sinusoid.al] diff --git a/third_party/immer/.gitignore b/third_party/immer/.gitignore deleted file mode 100644 index 2074141ec261..000000000000 --- a/third_party/immer/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -bazel-* -build/ -build-*/ -reports/ -doc/_build -doc/_doxygen -bazel-* - -tools/travis/ssh-key -tools/clojure/target/ -tools/scala/target/ -tools/scala/project/target/ - -extra/js/out -extra/js/boost - -__pycache__ - -.gdb_history - -.cache -tools/clojure/.lein* - -*.pyc diff --git a/third_party/immer/.skip-subtree b/third_party/immer/.skip-subtree deleted file mode 100644 index d49b47f75a16..000000000000 --- a/third_party/immer/.skip-subtree +++ /dev/null @@ -1 +0,0 @@ -Third-party code with non-depot layout. diff --git a/third_party/immer/.travis.yml b/third_party/immer/.travis.yml deleted file mode 100644 index cdbe09bf92fb..000000000000 --- a/third_party/immer/.travis.yml +++ /dev/null @@ -1,84 +0,0 @@ -language: nix -dist: trusty - -git: - depth: false - -matrix: - include: - - env: DO=check TYPE=Debug TOOLCHAIN=llvm-5 SANITIZE=true - - env: DO=check TYPE=Release TOOLCHAIN=llvm-5 BENCHMARKS=true - - env: DO=check TYPE=Debug TOOLCHAIN=gnu-6 COVERAGE=true - - env: DO=check TYPE=Release TOOLCHAIN=gnu-6 BENCHMARKS=true - - env: DO=check TYPE=Debug TOOLCHAIN=gnu-7 STD=17 - - env: DO=check TYPE=Debug TOOLCHAIN=llvm-9 STD=17 FUZZERS=true - - env: DO=build - - env: DO=docs - -before_install: - - | - : ${TOOLCHAIN:=gnu-6} - : ${TYPE:=Debug} - : ${STD:=14} - function build-p { [[ "${DO}" == build ]]; } - function check-p { [[ "${DO}" == check ]]; } - function docs-p { [[ "${DO}" == docs ]]; } - function coverage-p { [[ "${COVERAGE}" == true ]]; } - function benchmarks-p { [[ "${BENCHMARKS}" == true ]]; } - function deploy-p { - [[ "${TRAVIS_PULL_REQUEST}" == "false" && \ - "${TRAVIS_BRANCH}" == "master" ]] - } - function upload-p { - [[ -n "$encrypted_1c8d51d72e41_key" && \ - -n "$encrypted_1c8d51d72e41_iv" ]] - } - function decrypt-ssh-key { - openssl aes-256-cbc \ - -K $encrypted_1c8d51d72e41_key \ - -iv $encrypted_1c8d51d72e41_iv \ - -in tools/travis/ssh-key.enc \ - -out tools/travis/ssh-key -d - chmod 600 tools/travis/ssh-key - } - function with-nix { - nix-shell --argstr toolchain $TOOLCHAIN --run "set -e; $1" - } - -install: - - with-nix "echo == nix environment ok" - -before_script: - - | - with-nix " - mkdir build && cd build - cmake .. \ - -DCMAKE_BUILD_TYPE=${TYPE} \ - -DCHECK_SLOW_TESTS=false \ - -DCXX_STANDARD=${STD} \ - -DCHECK_BENCHMARKS=${BENCHMARKS} \ - -DENABLE_COVERAGE=${COVERAGE} \ - -DENABLE_SANITIZE=${SANITIZE} \ - -DCHECK_FUZZERS=${FUZZERS} \ - -DDISABLE_FREE_LIST=${SANITIZE} - " - -script: - - | - set -e - ! build-p || nix-build - ! check-p || with-nix "cd build && make -j2 check" - ! docs-p || with-nix "cd build && make docs" - -after_success: - - | - ! coverage-p || with-nix " - cd build - find . -name \"*.gcno\" | xargs gcov -bcprs ${PWD} - bash <(curl -s https://codecov.io/bash) -x gcov - " - if upload-p; then - decrypt-ssh-key - ! benchmarks-p || with-nix "cd build && make upload-benchmark-reports" - ! docs-p || ! deploy-p || with-nix "cd build && make upload-docs" - fi diff --git a/third_party/immer/BUILD b/third_party/immer/BUILD deleted file mode 100644 index 3d79830b60a3..000000000000 --- a/third_party/immer/BUILD +++ /dev/null @@ -1,11 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -cc_library( - name = "immer", - include_prefix = "immer", - strip_include_prefix = - "immer", - hdrs = glob([ - "immer/**/*.hpp", - ]), -) diff --git a/third_party/immer/CMakeLists.txt b/third_party/immer/CMakeLists.txt deleted file mode 100644 index dedfdf74013b..000000000000 --- a/third_party/immer/CMakeLists.txt +++ /dev/null @@ -1,141 +0,0 @@ - -cmake_minimum_required(VERSION 3.5.1) -cmake_policy(SET CMP0048 NEW) # enable project VERSION -cmake_policy(SET CMP0056 NEW) # honor link flags in try_compile() -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -project(immer VERSION 0.6.2) - -if (NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-extended-offsetof -Wno-c++17-extensions -Wno-c++1z-extensions -Wno-unknown-warning-option") -endif() -set(CMAKE_EXPORT_COMPILE_COMMANDS on) -set(CMAKE_CXX_EXTENSIONS off) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments") -endif() - -include(GNUInstallDirs) -include(ImmerUtils) - -# Options -# ======= - -option(ENABLE_SANITIZE "compile with sanitizers enabled") -option(ENABLE_COVERAGE "compile with test coverage support") -option(DISABLE_WERROR "enable --werror") -option(DISABLE_FREE_LIST "disables the free list heap") -option(DISABLE_THREAD_SAFETY "disables thread safety by default") -option(CHECK_FUZZERS "Add fuzzers as part of make check") - -option(ENABLE_PYTHON "enable building python module" off) -option(ENABLE_GUILE "enable building guile module" off) -option(ENABLE_BOOST_COROUTINE "run benchmarks with boost coroutine" off) - -option(immer_BUILD_TESTS "Build tests" ON) -option(immer_BUILD_EXAMPLES "Build examples" ON) -option(immer_BUILD_DOCS "Build docs" ON) -option(immer_BUILD_EXTRAS "Build extras" ON) - -set(CXX_STANDARD 14 CACHE STRING "c++ standard number") - -set(CMAKE_CXX_STANDARD ${CXX_STANDARD}) -set(CMAKE_CXX_STANDARD_REQUIRED on) - -if (ENABLE_SANITIZE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=leak") -endif() -if (NOT MSVC AND NOT DISABLE_WERROR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") -endif() - -# Dependencies -# ============ - -if (ENABLE_BOOST_COROUTINE) - set(immer_boost_components coroutine) -endif() - -find_package(Threads) -find_package(BoehmGC) -find_package(Boost 1.56 COMPONENTS ${immer_boost_components}) - -find_program(CCACHE ccache) -if (CCACHE) - message(STATUS "Using ccache: ${CCACHE}") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) -else() - message(STATUS "Could not find ccache") -endif() - -if (NOT BOEHM_GC_FOUND) - set(BOEHM_GC_LIBRARIES "") -endif() - -# Targets -# ======= - -# the library -add_library(immer INTERFACE) -target_include_directories(immer INTERFACE - $ - $ - $) -install(TARGETS immer EXPORT ImmerConfig) -install(EXPORT ImmerConfig DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Immer") -install(DIRECTORY immer DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - -# development target to be used in tests, examples, benchmarks... -immer_canonicalize_cmake_booleans( - DISABLE_FREE_LIST - DISABLE_THREAD_SAFETY - CHECK_SLOW_TESTS) -add_library(immer-dev INTERFACE) -target_include_directories(immer-dev SYSTEM INTERFACE - ${Boost_INCLUDE_DIR} - ${BOEHM_GC_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tools/include) -target_link_libraries(immer-dev INTERFACE - immer - ${BOEHM_GC_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT}) -target_compile_definitions(immer-dev INTERFACE - -DIMMER_CXX_STANDARD=${CXX_STANDARD} - -DIMMER_HAS_LIBGC=1 - -DIMMER_NO_FREE_LIST=${DISABLE_FREE_LIST} - -DIMMER_NO_THREAD_SAFETY=${DISABLE_THREAD_SAFETY} - -DIMMER_SLOW_TESTS=${CHECK_SLOW_TESTS}) -if (ENABLE_COVERAGE) - target_compile_options(immer-dev INTERFACE "--coverage") - target_link_libraries(immer-dev INTERFACE "--coverage") -endif() - -# Testing -# ======= - -if (immer_BUILD_TESTS) - enable_testing() - - add_custom_target(check - COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Build and run all the tests and examples.") - - add_subdirectory(test) - add_subdirectory(benchmark) -endif() - -if (immer_BUILD_EXAMPLES) - add_subdirectory(example) -endif() - -if (immer_BUILD_DOCS) - add_subdirectory(doc) -endif() - -if (immer_BUILD_EXTRAS) - add_subdirectory(extra/fuzzer) - add_subdirectory(extra/python) - add_subdirectory(extra/guile) -endif() diff --git a/third_party/immer/LICENSE b/third_party/immer/LICENSE deleted file mode 100644 index 36b7cd93cdfb..000000000000 --- a/third_party/immer/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/third_party/immer/README.rst b/third_party/immer/README.rst deleted file mode 100644 index afa2fecbb3bc..000000000000 --- a/third_party/immer/README.rst +++ /dev/null @@ -1,225 +0,0 @@ - -.. image:: https://travis-ci.org/arximboldi/immer.svg?branch=master - :target: https://travis-ci.org/arximboldi/immer - :alt: Travis Badge - -.. image:: https://codecov.io/gh/arximboldi/immer/branch/master/graph/badge.svg - :target: https://codecov.io/gh/arximboldi/immer - :alt: CodeCov Badge - -.. image:: https://cdn.rawgit.com/arximboldi/immer/355a113782aedc2ea22463444014809269c2376d/doc/_static/sinusoidal-badge.svg - :target: https://sinusoid.al - :alt: Sinusoidal Engineering badge - :align: right - -.. raw:: html - - Logotype - -.. include:introduction/start - -**immer** is a library of persistent_ and immutable_ data structures -written in C++. These enable whole new kinds of architectures for -interactive and concurrent programs of striking simplicity, -correctness, and performance. - -.. _persistent: https://en.wikipedia.org/wiki/Persistent_data_structure -.. _immutable: https://en.wikipedia.org/wiki/Immutable_object - -* **Documentation** (Contents_) -* **Code** (GitHub_) -* **CppCon'17 Talk**: *Postmodern Immutable Data Structures* (YouTube_, Slides_) -* **ICFP'17 Paper**: *Persistence for the masses* (Preprint_) - -.. _contents: https://sinusoid.es/immer/#contents -.. _github: https://github.com/arximboldi/immer -.. _youtube: https://www.youtube.com/watch?v=sPhpelUfu8Q -.. _slides: https://sinusoid.es/talks/immer-cppcon17 -.. _preprint: https://public.sinusoid.es/misc/immer/immer-icfp17.pdf - - - .. raw:: html - - - - - - This library has full months of *pro bono* research and development - invested in it. This is just the first step in a long-term vision - of making interactive and concurrent C++ programs easier to - write. **Put your logo here and help this project's long term - sustainability by buying a sponsorship package:** immer@sinusoid.al - -.. include:index/end - -Example -------- - -.. github does not support the ``literalinclude`` directive. This - example is copy pasted from ``example/vector/intro.cpp`` - -.. code-block:: c++ - - #include - int main() - { - const auto v0 = immer::vector{}; - const auto v1 = v0.push_back(13); - assert(v0.size() == 0 && v1.size() == 1 && v1[0] == 13); - - const auto v2 = v1.set(0, 42); - assert(v1[0] == 13 && v2[0] == 42); - } -.. - - For a **complete example** check `Ewig, a simple didactic - text-editor `_ built with this - library. You may also wanna check `Lager, a Redux-like library - `_ for writting interactive - software in C++ using a value-oriented design. - - -Why? ----- - -In the last few years, there has been a growing interest in immutable -data structures, motivated by the horizontal scaling of our processing -power and the ubiquity of highly interactive systems. Languages like -Clojure_ and Scala_ provide them by default, and implementations -for JavaScript like Mori_ and Immutable.js_ are widely used, -specially in combination with modern UI frameworks like React_. - -Interactivity - Thanks to *persistence* and *structural sharing*, new values can - be efficiently compared with old ones. This enables simpler ways of - *reasoning about change* that sit at the core of modern - interactive systems programming paradigms like `reactive - programming`_. - -Concurrency - Passing immutable data structures by value does not need to copy - any data. In the absence of mutation, data can be safely read - from multiple concurrent processes, and enable concurrency - patterns like `share by communicating`_ efficiently. - -Parallelism - Some recent immutable data structures have interesting properties - like :math:`O(log(n))` concatenation, which enable new kinds of - `parallelization algorithms`_. - -.. _clojure: http://clojure.org/reference/data_structures -.. _scala: http://docs.scala-lang.org/overviews/collections/overview.html - -.. _mori: https://swannodette.github.io/mori/ -.. _immutable.js: https://github.com/facebook/immutable-js -.. _react: https://facebook.github.io/react/ - -.. _reactive programming: https://en.wikipedia.org/wiki/Reactive_programming -.. _share by communicating: https://blog.golang.org/share-memory-by-communicating -.. _parallelization algorithms: http://docs.scala-lang.org/overviews/parallel-collections/overview.html - -Features --------- - -Idiomatic - This library doesn't pretend that it is written in Haskell. It - leverages features from recent standards to provide an API that is - both efficient and natural for a C++ developer. - -Performant - You use C++ because you need this. *Immer* implements state of - the art data structures with efficient cache utilization and have - been proven production ready in other languages. It also includes - our own improvements over that are only possible because of the - C++'s ability to abstract over memory layout. We monitor the - performance impact of every change by collecting `benchmark - results`_ directly from CI. - -.. _benchmark results: https://public.sinusoid.es/misc/immer/reports/ - -Customizable - We leverage templates and `policy-based design`_ to build - data-structures that can be adapted to work efficiently for - various purposes and architectures, for example, by choosing among - various `memory management strategies`. This turns - *immer* into a good foundation to provide immutable data - structures to higher level languages with a C runtime, like - Python_ or Guile_. - -.. _python: https://www.python.org/ -.. _guile: https://www.gnu.org/software/guile/ -.. _policy-based design: https://en.wikipedia.org/wiki/Policy-based_design -.. _memory management strategies: https://sinusoid.es/immer/memory.html - -Dependencies ------------- - -This library is written in **C++14** and a compliant compiler is -necessary. It is `continuously tested`_ with Clang 3.8 and GCC 6, but -it might work with other compilers and versions. - -No external library is necessary and there are no other requirements. - -.. _continuously tested: https://travis-ci.org/arximboldi/immer - -Usage ------ - -This is a **header only** library. You can just copy the ``immer`` -subfolder somewhere in your *include path*. - -If you are using the `Nix package manager`_ (we strongly recommend it) -you can just:: - - nix-env -if https://github.com/arximboldi/immer/archive/master.tar.gz - -Alternatively, you can use `CMake`_ to install the library in your -system once you have manually cloned the repository:: - - mkdir -p build && cd build - cmake .. && sudo make install - -.. _nix package manager: https://nixos.org/nix -.. _cmake: https://cmake.org/ - -Development ------------ - -In order to develop the library, you will need to compile and run the -examples, tests and benchmarks. These require some additional tools. -The easiest way to install them is by using the `Nix package -manager`_. At the root of the repository just type:: - - nix-shell - -This will download all required dependencies and create an isolated -environment in which you can use these dependencies, without polluting -your system. - -Then you can proceed to generate a development project using `CMake`_:: - - mkdir build && cd build - cmake .. - -From then on, one may build and run all tests by doing:: - - make check - -In order to build and run all benchmarks when running ``make check``, -run ``cmake`` again with the option ``-DCHECK_BENCHMARKS=1``. The -results of running the benchmarks will be saved to a folder -``reports/`` in the project root. - -License -------- - -**This software is licensed under the Boost Software License 1.0**. - -.. image:: https://upload.wikimedia.org/wikipedia/commons/c/cd/Boost.png - :alt: Boost logo - :target: http://boost.org/LICENSE_1_0.txt - :align: right - -The full text of the license is can be accessed `via this link -`_ and is also included -in the ``LICENSE`` file of this software package. diff --git a/third_party/immer/WORKSPACE b/third_party/immer/WORKSPACE deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/third_party/immer/benchmark/CMakeLists.txt b/third_party/immer/benchmark/CMakeLists.txt deleted file mode 100644 index 0f9061aa3cd3..000000000000 --- a/third_party/immer/benchmark/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ - -# Config -# ====== - -option(CHECK_BENCHMARKS "Run benchmarks on check target" off) -option(BENCHMARK_DISABLE_GC "Disable gc during a measurement") - -set(BENCHMARK_PARAM "N:1000" CACHE STRING "Benchmark parameters") -set(BENCHMARK_SAMPLES "20" CACHE STRING "Benchmark samples") - -# Dependencies -# ============ - -find_package(RRB) - -if (NOT RRB_FOUND) - message(STATUS "Disabling benchmarks") - return() -endif() - -# These are expected to be in the include path, the nix-shell -# environment installs them: -# -# https://github.com/marcusz/steady -# https://github.com/deepsea-inria/chunkedseq.git -# https://github.com/rsms/immutable-cpp.git - -# Targets -# ======= - -add_custom_target(benchmarks - COMMENT "Build all benchmarks.") - -execute_process( - COMMAND git log -1 --format=%h - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE immer_git_commit_hash - OUTPUT_STRIP_TRAILING_WHITESPACE) - -execute_process( - COMMAND git status --porcelain - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE immer_git_status - OUTPUT_STRIP_TRAILING_WHITESPACE) - -if (NOT immer_git_status STREQUAL "") - set(immer_git_commit_hash "${immer_git_commit_hash}+") -endif() - -site_name(immer_hostname) - -get_filename_component(immer_compiler_name "${CMAKE_CXX_COMPILER}" NAME) - -set(immer_benchmark_report_base_dir "${CMAKE_SOURCE_DIR}/reports") -set(immer_benchmark_report_dir "${immer_benchmark_report_base_dir}/report_\ -${immer_git_commit_hash}_\ -${immer_hostname}_\ -${immer_compiler_name}_\ -${BENCHMARK_PARAM}_\ -s${BENCHMARK_SAMPLES}") - -if(DISABLE_FREE_LIST) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nofl") -endif() - -if(DISABLE_THREAD_SAFETY) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nots") -endif() - -if(BENCHMARK_DISABLE_GC) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nogc") -endif() - -if(CHECK_BENCHMARKS) - add_dependencies(check benchmarks) -endif() - -add_custom_target(benchmark-report-dir - COMMAND ${CMAKE_COMMAND} - -E make_directory ${immer_benchmark_report_dir}) - -file(GLOB_RECURSE immer_benchmarks "*.cpp") -foreach(_file IN LISTS immer_benchmarks) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - add_dependencies(benchmarks ${_target}) - add_dependencies(${_target} benchmark-report-dir) - target_compile_options(${_target} PUBLIC -Wno-unused-function) - target_compile_definitions(${_target} PUBLIC - NONIUS_RUNNER - IMMER_BENCHMARK_LIBRRB=1 - IMMER_BENCHMARK_STEADY=1 - IMMER_BENCHMARK_EXPERIMENTAL=0 - IMMER_BENCHMARK_DISABLE_GC=${BENCHMARK_DISABLE_GC} - IMMER_BENCHMARK_BOOST_COROUTINE=${ENABLE_BOOST_COROUTINE}) - target_link_libraries(${_target} PUBLIC - immer-dev - ${RRB_LIBRARIES}) - target_include_directories(${_target} SYSTEM PUBLIC - ${RRB_INCLUDE_DIR}) - if(CHECK_BENCHMARKS) - add_test("benchmark/${_output}" "${CMAKE_SOURCE_DIR}/tools/with-tee.bash" - ${immer_benchmark_report_dir}/${_target}.out - "${CMAKE_CURRENT_BINARY_DIR}/${_output}" -v - -t ${_target} - -r html - -s ${BENCHMARK_SAMPLES} - -p ${BENCHMARK_PARAM} - -o ${immer_benchmark_report_dir}/${_target}.html) - endif() -endforeach() - -set(immer_ssh_method - ssh -p 5488 - -o StrictHostKeyChecking=no - -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key) - -add_custom_target(upload-benchmark-reports - COMMAND - rsync -av -e \"${immer_ssh_method}\" - ${immer_benchmark_report_base_dir} - raskolnikov@sinusoid.es:public/misc/immer/) - -add_custom_target(copy-benchmark-reports - COMMAND - rsync -av ${immer_benchmark_report_base_dir} - ~/public/misc/immer/) diff --git a/third_party/immer/benchmark/config.hpp b/third_party/immer/benchmark/config.hpp deleted file mode 100644 index c32ef5812ff8..000000000000 --- a/third_party/immer/benchmark/config.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include - -#include -#include - -namespace { - -NONIUS_PARAM(N, std::size_t{1000}) - -struct gc_disable -{ - gc_disable() - { -#if IMMER_BENCHMARK_DISABLE_GC - GC_disable(); -#else - GC_gcollect(); -#endif - } - ~gc_disable() - { -#if IMMER_BENCHMARK_DISABLE_GC - GC_enable(); - GC_gcollect(); -#endif - } - gc_disable(const gc_disable&) = delete; - gc_disable(gc_disable&&) = delete; -}; - -template -void measure(Meter& m, Fn&& fn) -{ - gc_disable guard; - return m.measure(std::forward(fn)); -} - -using def_memory = immer::default_memory_policy; -using gc_memory = immer::memory_policy, immer::no_refcount_policy>; -using gcf_memory = immer::memory_policy, immer::no_refcount_policy, immer::gc_transience_policy, false>; -using basic_memory = immer::memory_policy, immer::refcount_policy>; -using safe_memory = immer::memory_policy, immer::refcount_policy>; -using unsafe_memory = immer::memory_policy, immer::unsafe_refcount_policy>; - -} // anonymous namespace diff --git a/third_party/immer/benchmark/extra/refcounting.cpp b/third_party/immer/benchmark/extra/refcounting.cpp deleted file mode 100644 index c7c5183e6264..000000000000 --- a/third_party/immer/benchmark/extra/refcounting.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -NONIUS_PARAM(N, std::size_t{1000}) - -constexpr auto benchmark_size = 32u; - -struct object_t : immer::detail::ref_count_base -{}; - -auto make_data() -{ - auto objs = std::array, benchmark_size>(); - std::generate(objs.begin(), objs.end(), [] { - return std::make_unique(); - }); - auto refs = std::array(); - std::transform(objs.begin(), objs.end(), refs.begin(), [](auto& obj) { - return obj.get(); - }); - return make_pair(std::move(objs), - std::move(refs)); -} - -NONIUS_BENCHMARK("intrusive_ptr", [] (nonius::chronometer meter) -{ - auto arr = std::array, benchmark_size>{}; - auto storage = std::vector< - nonius::storage_for< - std::array, benchmark_size>>> ( - meter.runs()); - std::generate(arr.begin(), arr.end(), [] { - return new object_t{}; - }); - meter.measure([&] (int i) { - storage[i].construct(arr); - }); -}) - -NONIUS_BENCHMARK("generic", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - std::transform(refs.begin(), refs.end(), r, [] (auto& p) { - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - return p; - }); - return r; - }); -}) - -NONIUS_BENCHMARK("manual", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - unroll", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - auto e = refs.end(); - for (auto p = refs.begin(); p != e;) { - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - } - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - nocheck", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - constant", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto i = 0u; i < benchmark_size; ++i) - refs[i]->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - memcopy", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::memcpy(r, &refs[0], sizeof(object_t*) * benchmark_size); - return r; - }); -}) diff --git a/third_party/immer/benchmark/set/access.hpp b/third_party/immer/benchmark/set/access.hpp deleted file mode 100644 index 8605c0ff453c..000000000000 --- a/third_party/immer/benchmark/set/access.hpp +++ /dev/null @@ -1,175 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include -#include // Phil Nash -#include -#include -#include - -namespace { - -template -auto make_generator_ranged(std::size_t runs) -{ - assert(runs > 0); - auto engine = std::default_random_engine{13}; - auto dist = std::uniform_int_distribution{0, (T)runs-1}; - auto r = std::vector(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; -} - -template -auto benchmark_access_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[g2[i]]); - volatile auto r = c; - return r; - }); - }; -} - -template -auto benchmark_access_hamt() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) { - auto& x = g1[g2[i]]; - auto leaf = v.find(x).leaf(); - c += !!(leaf && leaf->find(x)); - } - volatile auto r = c; - return r; - }); - }; -} - - -template -auto benchmark_access() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[g2[i]]); - volatile auto r = c; - return r; - }); - }; -} - -template -auto benchmark_bad_access_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[n+i]); - volatile auto r = c; - return r; - }); - }; -} - -template -auto benchmark_bad_access_hamt() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) { - auto& x = g1[n+i]; - auto leaf = v.find(x).leaf(); - c += !!(leaf && leaf->find(x)); - } - volatile auto r = c; - return r; - }); - }; -} - - -template -auto benchmark_bad_access() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[n+i]); - volatile auto r = c; - return r; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/access.ipp b/third_party/immer/benchmark/set/access.ipp deleted file mode 100644 index f026d9cfa736..000000000000 --- a/third_party/immer/benchmark/set/access.ipp +++ /dev/null @@ -1,30 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "access.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("std::set", benchmark_access_std>()) -NONIUS_BENCHMARK("std::unordered_set", benchmark_access_std>()) -NONIUS_BENCHMARK("boost::flat_set", benchmark_access_std>()) -NONIUS_BENCHMARK("hamt::hash_trie", benchmark_access_hamt>()) -NONIUS_BENCHMARK("immer::set/5B", benchmark_access,std::equal_to,def_memory,5>>()) -NONIUS_BENCHMARK("immer::set/4B", benchmark_access,std::equal_to,def_memory,4>>()) - -NONIUS_BENCHMARK("bad/std::set", benchmark_bad_access_std>()) -NONIUS_BENCHMARK("bad/std::unordered_set", benchmark_bad_access_std>()) -NONIUS_BENCHMARK("bad/boost::flat_set", benchmark_bad_access_std>()) -NONIUS_BENCHMARK("bad/hamt::hash_trie", benchmark_bad_access_hamt>()) -NONIUS_BENCHMARK("bad/immer::set/5B", benchmark_bad_access,std::equal_to,def_memory,5>>()) -NONIUS_BENCHMARK("bad/immer::set/4B", benchmark_bad_access,std::equal_to,def_memory,4>>()) diff --git a/third_party/immer/benchmark/set/insert.hpp b/third_party/immer/benchmark/set/insert.hpp deleted file mode 100644 index be679b4de342..000000000000 --- a/third_party/immer/benchmark/set/insert.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include -#include // Phil Nash -#include -#include -#include - -namespace { - -template -auto benchmark_insert_mut_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g = Generator{}(n); - - measure(meter, [&] { - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g[i]); - return v; - }); - }; -} - -template -auto benchmark_insert() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g = Generator{}(n); - - measure(meter, [&] { - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g[i]); - return v; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/insert.ipp b/third_party/immer/benchmark/set/insert.ipp deleted file mode 100644 index 6717ccd57ea7..000000000000 --- a/third_party/immer/benchmark/set/insert.ipp +++ /dev/null @@ -1,28 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "insert.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("std::set", benchmark_insert_mut_std>()) -NONIUS_BENCHMARK("std::unordered_set", benchmark_insert_mut_std>()) -NONIUS_BENCHMARK("boost::flat_set", benchmark_insert_mut_std>()) -NONIUS_BENCHMARK("hamt::hash_trie", benchmark_insert_mut_std>()) - -NONIUS_BENCHMARK("immer::set/5B", benchmark_insert,std::equal_to,def_memory,5>>()) -NONIUS_BENCHMARK("immer::set/4B", benchmark_insert,std::equal_to,def_memory,4>>()) -#ifndef DISABLE_GC_BENCHMARKS -NONIUS_BENCHMARK("immer::set/GC", benchmark_insert,std::equal_to,gc_memory,5>>()) -#endif -NONIUS_BENCHMARK("immer::set/UN", benchmark_insert,std::equal_to,unsafe_memory,5>>()) diff --git a/third_party/immer/benchmark/set/iter.hpp b/third_party/immer/benchmark/set/iter.hpp deleted file mode 100644 index 91dd48644367..000000000000 --- a/third_party/immer/benchmark/set/iter.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include -#include -#include -#include // Phil Nash -#include -#include -#include -#include - -namespace { - -template -struct iter_step -{ - unsigned operator() (unsigned x, const T& y) const - { - return x + y; - } -}; - -template <> -struct iter_step -{ - unsigned operator() (unsigned x, const std::string& y) const - { - return x + (unsigned) y.size(); - } -}; - -template <> -struct iter_step> -{ - unsigned operator() (unsigned x, const immer::box& y) const - { - return x + (unsigned) y->size(); - } -}; - -template -auto benchmark_access_std_iter() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - using step_t = iter_step; - measure(meter, [&] { - volatile auto c = std::accumulate(v.begin(), v.end(), 0u, step_t{}); - return c; - }); - }; -} - -template -auto benchmark_access_reduce() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - using step_t = iter_step; - measure(meter, [&] { - volatile auto c = immer::accumulate(v, 0u, step_t{}); - return c; - }); - }; -} - -template -auto benchmark_access_iter() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - using step_t = iter_step; - measure(meter, [&] { - volatile auto c = std::accumulate(v.begin(), v.end(), 0u, step_t{}); - return c; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/iter.ipp b/third_party/immer/benchmark/set/iter.ipp deleted file mode 100644 index f8c3cb9695cd..000000000000 --- a/third_party/immer/benchmark/set/iter.ipp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "iter.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("iter/std::set", benchmark_access_std_iter>()) -NONIUS_BENCHMARK("iter/std::unordered_set", benchmark_access_std_iter>()) -NONIUS_BENCHMARK("iter/boost::flat_set", benchmark_access_std_iter>()) -NONIUS_BENCHMARK("iter/hamt::hash_trie", benchmark_access_std_iter>()) -NONIUS_BENCHMARK("iter/immer::set/5B", benchmark_access_iter,std::equal_to,def_memory,5>>()) -NONIUS_BENCHMARK("iter/immer::set/4B", benchmark_access_iter,std::equal_to,def_memory,4>>()) -NONIUS_BENCHMARK("reduce/immer::set/5B", benchmark_access_reduce,std::equal_to,def_memory,5>>()) -NONIUS_BENCHMARK("reduce/immer::set/4B", benchmark_access_reduce,std::equal_to,def_memory,4>>()) diff --git a/third_party/immer/benchmark/set/string-box/access.cpp b/third_party/immer/benchmark/set/string-box/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-box/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-box/generator.ipp b/third_party/immer/benchmark/set/string-box/generator.ipp deleted file mode 100644 index 9adc82e0bdc0..000000000000 --- a/third_party/immer/benchmark/set/string-box/generator.ipp +++ /dev/null @@ -1,46 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include -#include -#include -#include -#include - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 64; - static constexpr auto min_length = 8; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution{}; - auto gen = std::bind(dist, engine); - auto r = std::vector>(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-box/insert.cpp b/third_party/immer/benchmark/set/string-box/insert.cpp deleted file mode 100644 index c5762498c23c..000000000000 --- a/third_party/immer/benchmark/set/string-box/insert.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define DISABLE_GC_BENCHMARKS -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-box/iter.cpp b/third_party/immer/benchmark/set/string-box/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-box/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/string-long/access.cpp b/third_party/immer/benchmark/set/string-long/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-long/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-long/generator.ipp b/third_party/immer/benchmark/set/string-long/generator.ipp deleted file mode 100644 index 386364cc96fe..000000000000 --- a/third_party/immer/benchmark/set/string-long/generator.ipp +++ /dev/null @@ -1,44 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include -#include -#include - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 256; - static constexpr auto min_length = 32; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution{}; - auto gen = std::bind(dist, engine); - auto r = std::vector(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-long/insert.cpp b/third_party/immer/benchmark/set/string-long/insert.cpp deleted file mode 100644 index c5762498c23c..000000000000 --- a/third_party/immer/benchmark/set/string-long/insert.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define DISABLE_GC_BENCHMARKS -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-long/iter.cpp b/third_party/immer/benchmark/set/string-long/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-long/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/string-short/access.cpp b/third_party/immer/benchmark/set/string-short/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-short/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-short/generator.ipp b/third_party/immer/benchmark/set/string-short/generator.ipp deleted file mode 100644 index bd40d2d639a8..000000000000 --- a/third_party/immer/benchmark/set/string-short/generator.ipp +++ /dev/null @@ -1,44 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include -#include -#include - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 15; - static constexpr auto min_length = 4; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution{}; - auto gen = std::bind(dist, engine); - auto r = std::vector(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-short/insert.cpp b/third_party/immer/benchmark/set/string-short/insert.cpp deleted file mode 100644 index 26dfbce29204..000000000000 --- a/third_party/immer/benchmark/set/string-short/insert.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-short/iter.cpp b/third_party/immer/benchmark/set/string-short/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-short/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/access.cpp b/third_party/immer/benchmark/set/unsigned/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/unsigned/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/generator.ipp b/third_party/immer/benchmark/set/unsigned/generator.ipp deleted file mode 100644 index 2a2a2a0fb627..000000000000 --- a/third_party/immer/benchmark/set/unsigned/generator.ipp +++ /dev/null @@ -1,32 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include -#include -#include - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution{}; - auto r = std::vector(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/unsigned/insert.cpp b/third_party/immer/benchmark/set/unsigned/insert.cpp deleted file mode 100644 index 26dfbce29204..000000000000 --- a/third_party/immer/benchmark/set/unsigned/insert.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/iter.cpp b/third_party/immer/benchmark/set/unsigned/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/unsigned/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/vector/access.hpp b/third_party/immer/benchmark/vector/access.hpp deleted file mode 100644 index 4dff7a667f33..000000000000 --- a/third_party/immer/benchmark/vector/access.hpp +++ /dev/null @@ -1,261 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -#include - -#if IMMER_BENCHMARK_BOOST_COROUTINE -#include -#endif - -namespace { - -template -auto benchmark_access_reduce_chunkedseq() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto init = 0u; - v.for_each_segment([&] (auto first, auto last) { - init = std::accumulate(first, last, init); - }); - return init; - }; - }; -} - -template -auto benchmark_access_iter_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto volatile x = std::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -template -auto benchmark_access_idx_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[i]; - volatile auto rr = r; - return rr; - }; - }; -} - -template -auto benchmark_access_random_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - auto v = Vektor{}; - auto g = make_generator(n); - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[g[i]]; - volatile auto rr = r; - return rr; - }; - }; -} - -template -auto benchmark_access_iter() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = std::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -#if IMMER_BENCHMARK_BOOST_COROUTINE -template -auto benchmark_access_coro() -{ - return [] (nonius::parameters params) - { - using coro_t = typename boost::coroutines2::coroutine; - - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto c = coro_t::pull_type { [&](auto& sink) { - v.for_each_chunk([&](auto f, auto l) { - for (; f != l; ++f) - sink(*f); - }); - }}; - auto volatile x = std::accumulate(begin(c), end(c), 0u); - return x; - }; - }; -} -#endif - -template -auto benchmark_access_idx() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[i]; - volatile auto rr = r; - return rr; - }; - }; -} - -template -auto benchmark_access_reduce() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = immer::accumulate(v, 0u); - return x; - }; - }; -} - -template -auto benchmark_access_reduce_range() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = immer::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -template -auto benchmark_access_random() -{ - return [] (nonius::parameters params) - { - auto n = params.get(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - auto g = make_generator(n); - - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[g[i]]; - volatile auto rr = r; - return rr; - }; - }; -} - -template -auto benchmark_access_librrb(Fn maker) -{ - return - [=] (nonius::parameters params) { - auto n = params.get(); - auto v = maker(n); - return - [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += reinterpret_cast(rrb_nth(v, i)); - volatile auto rr = r; - return rr; - }; - }; -} - -template -auto benchmark_access_random_librrb(Fn maker) -{ - return - [=] (nonius::parameters params) { - auto n = params.get(); - auto v = maker(n); - auto g = make_generator(n); - return - [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += reinterpret_cast(rrb_nth(v, g[i])); - volatile auto rr = r; - return rr; - }; - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/assoc.hpp b/third_party/immer/benchmark/vector/assoc.hpp deleted file mode 100644 index 5619d7ee6936..000000000000 --- a/third_party/immer/benchmark/vector/assoc.hpp +++ /dev/null @@ -1,245 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template -auto benchmark_assoc_std() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = Vektor(n, 0); - std::iota(v.begin(), v.end(), 0u); - auto all = std::vector(meter.runs(), v); - meter.measure([&] (int iter) { - auto& r = all[iter]; - for (auto i = 0u; i < n; ++i) - r[i] = n - i; - return r; - }); - }; -} - -template -auto benchmark_assoc_random_std() -{ - return - [](nonius::chronometer meter) - { - auto n = meter.param(); - auto g = make_generator(n); - auto v = Vektor(n, 0); - std::iota(v.begin(), v.end(), 0u); - auto all = std::vector(meter.runs(), v); - meter.measure([&] (int iter) { - auto& r = all[iter]; - for (auto i = 0u; i < n; ++i) - r[g[i]] = n - i; - return r; - }); - }; -} - -template -auto benchmark_assoc() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = SetFn{}(r, i, n - i); - return r; - }); - }; -} - -template -auto benchmark_assoc_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = std::move(r).set(i, n - i); - return r; - }); - }; -} - -template -auto benchmark_assoc_random() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - auto g = make_generator(n); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = SetFn{}(r, g[i], i); - return r; - }); - }; -} - -template -auto benchmark_assoc_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v.transient(); - for (auto i = 0u; i < n; ++i) - r.set(i, n - i); - return r; - }); - }; -} - -template -auto benchmark_assoc_mut_random() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - auto g = make_generator(n); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v.transient(); - for (auto i = 0u; i < n; ++i) - r.set(g[i], i); - return r; - }); - }; -} - -template -auto benchmark_assoc_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n); - measure( - meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_update(r, i, reinterpret_cast(n - i)); - return r; - }); - }; -} - -template -auto benchmark_assoc_random_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n); - auto g = make_generator(n); - measure( - meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_update(r, g[i], reinterpret_cast(i)); - return r; - }); - }; -} - -template -auto benchmark_assoc_mut_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_update( - r, i, reinterpret_cast(i)); - return r; - }); - }; -} - -template -auto benchmark_assoc_mut_random_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n); - auto g = make_generator(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_update( - r, g[i], reinterpret_cast(i)); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/branching/access.ipp b/third_party/immer/benchmark/vector/branching/access.ipp deleted file mode 100644 index bd7f985d4df0..000000000000 --- a/third_party/immer/benchmark/vector/branching/access.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" -#include - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_access_idx>()) -NONIUS_BENCHMARK("flex/4", benchmark_access_idx>()) -NONIUS_BENCHMARK("flex/5", benchmark_access_idx>()) -NONIUS_BENCHMARK("flex/6", benchmark_access_idx>()) -NONIUS_BENCHMARK("flex/7", benchmark_access_idx>()) diff --git a/third_party/immer/benchmark/vector/branching/assoc.ipp b/third_party/immer/benchmark/vector/branching/assoc.ipp deleted file mode 100644 index 4aa9984f9275..000000000000 --- a/third_party/immer/benchmark/vector/branching/assoc.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/4", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/5", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/6", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/7", benchmark_assoc>()) diff --git a/third_party/immer/benchmark/vector/branching/basic/access.cpp b/third_party/immer/benchmark/vector/branching/basic/access.cpp deleted file mode 100644 index 23eb25565da0..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/assoc.cpp b/third_party/immer/benchmark/vector/branching/basic/assoc.cpp deleted file mode 100644 index 210a432abab2..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/concat.cpp b/third_party/immer/benchmark/vector/branching/basic/concat.cpp deleted file mode 100644 index 21163bdc0b94..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/push.cpp b/third_party/immer/benchmark/vector/branching/basic/push.cpp deleted file mode 100644 index 6be28f9219f5..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/concat.ipp b/third_party/immer/benchmark/vector/branching/concat.ipp deleted file mode 100644 index 0e21ca0b111f..000000000000 --- a/third_party/immer/benchmark/vector/branching/concat.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" -#include - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_concat>()) -NONIUS_BENCHMARK("flex/4", benchmark_concat>()) -NONIUS_BENCHMARK("flex/5", benchmark_concat>()) -NONIUS_BENCHMARK("flex/6", benchmark_concat>()) -NONIUS_BENCHMARK("flex/7", benchmark_concat>()) diff --git a/third_party/immer/benchmark/vector/branching/gc/access.cpp b/third_party/immer/benchmark/vector/branching/gc/access.cpp deleted file mode 100644 index cec060481c73..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/assoc.cpp b/third_party/immer/benchmark/vector/branching/gc/assoc.cpp deleted file mode 100644 index 448b2fd2ff79..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/concat.cpp b/third_party/immer/benchmark/vector/branching/gc/concat.cpp deleted file mode 100644 index 6c32ca821c8f..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/push.cpp b/third_party/immer/benchmark/vector/branching/gc/push.cpp deleted file mode 100644 index f1d1e33b9243..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/push.ipp b/third_party/immer/benchmark/vector/branching/push.ipp deleted file mode 100644 index 2f92d6569220..000000000000 --- a/third_party/immer/benchmark/vector/branching/push.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" -#include - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_push>()) -NONIUS_BENCHMARK("flex/4", benchmark_push>()) -NONIUS_BENCHMARK("flex/5", benchmark_push>()) -NONIUS_BENCHMARK("flex/6", benchmark_push>()) -NONIUS_BENCHMARK("flex/7", benchmark_push>()) diff --git a/third_party/immer/benchmark/vector/branching/safe/access.cpp b/third_party/immer/benchmark/vector/branching/safe/access.cpp deleted file mode 100644 index 027aa1b7619e..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/assoc.cpp b/third_party/immer/benchmark/vector/branching/safe/assoc.cpp deleted file mode 100644 index c2f5b0cc2034..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/concat.cpp b/third_party/immer/benchmark/vector/branching/safe/concat.cpp deleted file mode 100644 index 3c5dbb8a70a2..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/push.cpp b/third_party/immer/benchmark/vector/branching/safe/push.cpp deleted file mode 100644 index 19d5bbd254ea..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/access.cpp b/third_party/immer/benchmark/vector/branching/unsafe/access.cpp deleted file mode 100644 index 156d84e71763..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp b/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp deleted file mode 100644 index ff1802c0bc76..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp b/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp deleted file mode 100644 index d6d401bd483d..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/push.cpp b/third_party/immer/benchmark/vector/branching/unsafe/push.cpp deleted file mode 100644 index 09ba8d7a3759..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/common.hpp b/third_party/immer/benchmark/vector/common.hpp deleted file mode 100644 index c96d6d017d9c..000000000000 --- a/third_party/immer/benchmark/vector/common.hpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include -#include - -#include "benchmark/config.hpp" - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#include -#endif - -namespace immer { -template class array; -} // namespace immer - -namespace { - -auto make_generator(std::size_t runs) -{ - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution{0, runs-1}; - auto r = std::vector(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; -} - -struct push_back_fn -{ - template - auto operator() (T&& v, U&& x) - { return std::forward(v).push_back(std::forward(x)); } -}; - -struct push_front_fn -{ - template - auto operator() (T&& v, U&& x) - { return std::forward(v).push_front(std::forward(x)); } -}; - -struct set_fn -{ - template - decltype(auto) operator() (T&& v, I i, U&& x) - { return std::forward(v).set(i, std::forward(x)); } -}; - -struct store_fn -{ - template - decltype(auto) operator() (T&& v, I i, U&& x) - { return std::forward(v).store(i, std::forward(x)); } -}; - -template -struct get_limit : std::integral_constant< - std::size_t, std::numeric_limits::max()> {}; - -template -struct get_limit> : std::integral_constant< - std::size_t, 10000> {}; - -auto make_librrb_vector(std::size_t n) -{ - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - v = rrb_push(v, reinterpret_cast(i)); - } - return v; -} - -auto make_librrb_vector_f(std::size_t n) -{ - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - auto f = rrb_push(rrb_create(), - reinterpret_cast(i)); - v = rrb_concat(f, v); - } - return v; -} - - -// copied from: -// https://github.com/ivmai/bdwgc/blob/master/include/gc_allocator.h - -template -struct GC_type_traits -{ - std::false_type GC_is_ptr_free; -}; - -# define GC_DECLARE_PTRFREE(T) \ - template<> struct GC_type_traits { \ - std::true_type GC_is_ptr_free; \ - } - -GC_DECLARE_PTRFREE(char); -GC_DECLARE_PTRFREE(signed char); -GC_DECLARE_PTRFREE(unsigned char); -GC_DECLARE_PTRFREE(signed short); -GC_DECLARE_PTRFREE(unsigned short); -GC_DECLARE_PTRFREE(signed int); -GC_DECLARE_PTRFREE(unsigned int); -GC_DECLARE_PTRFREE(signed long); -GC_DECLARE_PTRFREE(unsigned long); -GC_DECLARE_PTRFREE(float); -GC_DECLARE_PTRFREE(double); -GC_DECLARE_PTRFREE(long double); - -template -inline void* GC_selective_alloc(size_t n, IsPtrFree, bool ignore_off_page) -{ - return ignore_off_page - ? GC_MALLOC_IGNORE_OFF_PAGE(n) - : GC_MALLOC(n); -} - -template <> -inline void* GC_selective_alloc(size_t n, - std::true_type, - bool ignore_off_page) -{ - return ignore_off_page - ? GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(n) - : GC_MALLOC_ATOMIC(n); -} - -template -class gc_allocator -{ -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template struct rebind { - typedef gc_allocator other; - }; - - gc_allocator() {} - gc_allocator(const gc_allocator&) throw() {} - template - explicit gc_allocator(const gc_allocator&) throw() {} - ~gc_allocator() throw() {} - - pointer address(reference GC_x) const { return &GC_x; } - const_pointer address(const_reference GC_x) const { return &GC_x; } - - // GC_n is permitted to be 0. The C++ standard says nothing about what - // the return value is when GC_n == 0. - T* allocate(size_type GC_n, const void* = 0) - { - GC_type_traits traits; - return static_cast - (GC_selective_alloc(GC_n * sizeof(T), - traits.GC_is_ptr_free, false)); - } - - // p is not permitted to be a null pointer. - void deallocate(pointer p, size_type /* GC_n */) - { GC_FREE(p); } - - size_type max_size() const throw() - { return size_t(-1) / sizeof(T); } - - void construct(pointer p, const T& __val) { new(p) T(__val); } - void destroy(pointer p) { p->~T(); } -}; - -template<> -class gc_allocator -{ - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template struct rebind { - typedef gc_allocator other; - }; -}; - -template -inline bool operator==(const gc_allocator&, const gc_allocator&) -{ return true; } - -template -inline bool operator!=(const gc_allocator&, const gc_allocator&) -{ return false; } - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/concat.hpp b/third_party/immer/benchmark/vector/concat.hpp deleted file mode 100644 index 8656587d5dbd..000000000000 --- a/third_party/immer/benchmark/vector/concat.hpp +++ /dev/null @@ -1,166 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -constexpr auto concat_steps = 10u; - -template -auto benchmark_concat() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - return v + v; - }); - }; -} - -template -auto benchmark_concat_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n); - measure(meter, [&] { - return rrb_concat(v, v); - }); - }; -} - -template -auto benchmark_concat_incr() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n / concat_steps; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = Vektor{}; - for (auto i = 0u; i < concat_steps; ++i) - r = r + v; - return r; - }); - }; -} - -template -auto benchmark_concat_incr_mut() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}.transient(); - for (auto i = 0u; i < n / concat_steps; ++i) - v.push_back(i); - - measure(meter, [&] (int run) { - auto r = Vektor{}.transient(); - for (auto i = 0u; i < concat_steps; ++i) - r.append(v); - return r; - }); - }; -} - -template -auto benchmark_concat_incr_mut2() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param(); - - using transient_t = typename Vektor::transient_type; - using steps_t = std::vector>; - auto vs = std::vector>(meter.runs()); - for (auto k = 0u; k < vs.size(); ++k) { - vs[k].reserve(concat_steps); - for (auto j = 0u; j < concat_steps; ++j) { - auto vv = Vektor{}.transient(); - for (auto i = 0u; i < n / concat_steps; ++i) - vv.push_back(i); - vs[k].push_back(std::move(vv)); - } - } - measure(meter, [&] (int run) { - auto& vr = vs[run]; - auto r = Vektor{}.transient(); - assert(vr.size() == concat_steps); - for (auto i = 0u; i < concat_steps; ++i) - r.append(std::move(vr[i])); - return r; - }); - }; -} - -template -auto benchmark_concat_incr_chunkedseq() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param(); - - using steps_t = std::vector; - auto vs = std::vector(meter.runs()); - for (auto k = 0u; k < vs.size(); ++k) { - for (auto j = 0u; j < concat_steps; ++j) { - auto vv = Vektor{}; - for (auto i = 0u; i < n / concat_steps; ++i) - vv.push_back(i); - vs[k].push_back(std::move(vv)); - } - } - measure(meter, [&] (int run) { - auto& vr = vs[run]; - auto r = Vektor{}; - for (auto i = 0u; i < concat_steps; ++i) - r.concat(vr[i]); - return r; - }); - }; -} - -template -auto benchmark_concat_incr_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param(); - auto v = maker(n / concat_steps); - measure(meter, [&] { - auto r = rrb_create(); - for (auto i = 0ul; i < concat_steps; ++i) - r = rrb_concat(r, v); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/drop.hpp b/third_party/immer/benchmark/vector/drop.hpp deleted file mode 100644 index 0a525f67a50a..000000000000 --- a/third_party/immer/benchmark/vector/drop.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template -auto benchmark_drop() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - (void) v.drop(i); - }); - }; -} - -template -auto benchmark_drop_lin() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = r.drop(1); - return r; - }); - }; -} - -template -auto benchmark_drop_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = std::move(r).drop(1); - return r; - }); - }; -} - -template -auto benchmark_drop_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto vv = Vektor{}; - for (auto i = 0u; i < n; ++i) - vv = PushFn{}(std::move(vv), i); - - measure(meter, [&] { - auto v = vv.transient(); - for (auto i = 0u; i < n; ++i) - (void) v.drop(1); - }); - }; -} - -template -auto benchmark_drop_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - rrb_slice(v, i, n); - }); - }; -} - -template -auto benchmark_drop_lin_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_slice(r, 1, n); - return r; - }); - }; -} - -template -auto benchmark_drop_mut_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure(meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_slice(r, 1, n); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/misc/access.cpp b/third_party/immer/benchmark/vector/misc/access.cpp deleted file mode 100644 index 9a00266a87d8..000000000000 --- a/third_party/immer/benchmark/vector/misc/access.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" - -#include -#include -#include -#include - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include -#endif - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include -#endif - -#include -#include -#include - -NONIUS_BENCHMARK("std::vector", benchmark_access_iter_std>()) -NONIUS_BENCHMARK("std::vector/idx", benchmark_access_idx_std>()) -NONIUS_BENCHMARK("std::vector/random", benchmark_access_random_std>()) -NONIUS_BENCHMARK("std::list", benchmark_access_iter_std>()) - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_access_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_access_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("librrb/random", benchmark_access_random_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F/random", benchmark_access_random_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("flex/5B", benchmark_access_iter>()) -NONIUS_BENCHMARK("flex/F/5B", benchmark_access_iter,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B", benchmark_access_iter>()) -NONIUS_BENCHMARK("vector/5B", benchmark_access_iter>()) -NONIUS_BENCHMARK("vector/6B", benchmark_access_iter>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_access_iter>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_access_iter>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_access_iter>()) -#endif - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/idx", benchmark_access_idx>()) -#endif - -NONIUS_BENCHMARK("flex/5B/idx", benchmark_access_idx>()) -NONIUS_BENCHMARK("flex/F/5B/idx", benchmark_access_idx,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/idx", benchmark_access_idx>()) -NONIUS_BENCHMARK("vector/5B/idx", benchmark_access_idx>()) -NONIUS_BENCHMARK("vector/6B/idx", benchmark_access_idx>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/idx", benchmark_access_idx>()) -NONIUS_BENCHMARK("dvektor/5B/idx", benchmark_access_idx>()) -NONIUS_BENCHMARK("dvektor/6B/idx", benchmark_access_idx>()) -#endif - -NONIUS_BENCHMARK("flex/5B/reduce_i", benchmark_access_reduce_range>()) -NONIUS_BENCHMARK("vector/5B/reduce_i", benchmark_access_reduce_range>()) - -NONIUS_BENCHMARK("flex/5B/reduce", benchmark_access_reduce>()) -NONIUS_BENCHMARK("flex/F/5B/reduce", benchmark_access_reduce,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/reduce", benchmark_access_reduce>()) -NONIUS_BENCHMARK("vector/5B/reduce", benchmark_access_reduce>()) -NONIUS_BENCHMARK("vector/6B/reduce", benchmark_access_reduce>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/random", benchmark_access_random>()) -#endif - -NONIUS_BENCHMARK("flex/5B/random", benchmark_access_random>()) -NONIUS_BENCHMARK("flex/F/5B/random", benchmark_access_random, push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/random", benchmark_access_random>()) -NONIUS_BENCHMARK("vector/5B/random", benchmark_access_random>()) -NONIUS_BENCHMARK("vector/6B/random", benchmark_access_random>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/random", benchmark_access_random>()) -NONIUS_BENCHMARK("dvektor/5B/random", benchmark_access_random>()) -NONIUS_BENCHMARK("dvektor/6B/random", benchmark_access_random>()) -#endif - -#if IMMER_BENCHMARK_BOOST_COROUTINE -NONIUS_BENCHMARK("vector/5B/coro", benchmark_access_coro>()) -#endif diff --git a/third_party/immer/benchmark/vector/misc/assoc.cpp b/third_party/immer/benchmark/vector/misc/assoc.cpp deleted file mode 100644 index 2b3d6d76b985..000000000000 --- a/third_party/immer/benchmark/vector/misc/assoc.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" - -#include -#include -#include -#include -#include - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include -#endif - -#include -#include -#include - -#include -#include - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include -#endif - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -NONIUS_BENCHMARK("std::vector", benchmark_assoc_std>()) -NONIUS_BENCHMARK("std::vector/random", benchmark_assoc_random_std>()) - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_assoc_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_assoc_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("librrb/random", benchmark_assoc_random_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb", benchmark_assoc_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_assoc_mut_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb/random", benchmark_assoc_mut_random_librrb(make_librrb_vector)) -#endif - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady", benchmark_assoc, push_back_fn, store_fn>()) -#endif - -NONIUS_BENCHMARK("flex/5B", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/F/5B", benchmark_assoc,push_front_fn>()) - -NONIUS_BENCHMARK("flex/GC", benchmark_assoc>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_assoc,push_front_fn>()) - -NONIUS_BENCHMARK("flex_s/GC", benchmark_assoc>()) -NONIUS_BENCHMARK("flex_s/F/GC",benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GCF",benchmark_assoc,push_front_fn>()) - -NONIUS_BENCHMARK("vector/4B", benchmark_assoc>()) -NONIUS_BENCHMARK("vector/5B", benchmark_assoc>()) -NONIUS_BENCHMARK("vector/6B", benchmark_assoc>()) - -NONIUS_BENCHMARK("vector/GC", benchmark_assoc>()) -NONIUS_BENCHMARK("vector/NO", benchmark_assoc>()) -NONIUS_BENCHMARK("vector/UN", benchmark_assoc>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_assoc>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_assoc>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_assoc>()) - -NONIUS_BENCHMARK("dvektor/GC", benchmark_assoc>()) -NONIUS_BENCHMARK("dvektor/NO", benchmark_assoc>()) -NONIUS_BENCHMARK("dvektor/UN", benchmark_assoc>()) -#endif - -NONIUS_BENCHMARK("array", benchmark_assoc>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/random", benchmark_assoc_random, push_back_fn, store_fn>()) -#endif - -NONIUS_BENCHMARK("flex/5B/random", benchmark_assoc_random>()) -NONIUS_BENCHMARK("vector/4B/random", benchmark_assoc_random>()) -NONIUS_BENCHMARK("vector/5B/random", benchmark_assoc_random>()) -NONIUS_BENCHMARK("vector/6B/random", benchmark_assoc_random>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/random", benchmark_assoc_random>()) -NONIUS_BENCHMARK("dvektor/5B/random", benchmark_assoc_random>()) -NONIUS_BENCHMARK("dvektor/6B/random", benchmark_assoc_random>()) -#endif -NONIUS_BENCHMARK("array/random", benchmark_assoc_random>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_assoc_mut,push_front_fn>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_assoc_move>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_assoc_move>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_assoc_move>()) -NONIUS_BENCHMARK("m/vector/UN", benchmark_assoc_move>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_assoc_move,push_front_fn>()) - -NONIUS_BENCHMARK("t/vector/5B/random", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("t/vector/GC/random", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("t/vector/NO/random", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("t/vector/UN/random", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("t/flex/F/5B/random", benchmark_assoc_mut_random,push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/misc/concat.cpp b/third_party/immer/benchmark/vector/misc/concat.cpp deleted file mode 100644 index 9bc10c5c2309..000000000000 --- a/third_party/immer/benchmark/vector/misc/concat.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" - -#include -#include -#include -#include -#include - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_concat_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_concat_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("i/librrb", benchmark_concat_incr_librrb(make_librrb_vector)) -#endif - -NONIUS_BENCHMARK("flex/4B", benchmark_concat>()) -NONIUS_BENCHMARK("flex/5B", benchmark_concat>()) -NONIUS_BENCHMARK("flex/6B", benchmark_concat>()) -NONIUS_BENCHMARK("flex/GC", benchmark_concat>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_concat>()) -NONIUS_BENCHMARK("flex/NO", benchmark_concat>()) -NONIUS_BENCHMARK("flex/UN", benchmark_concat>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_concat,push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_concat,push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_concat,push_front_fn>()) - -NONIUS_BENCHMARK("i/flex/GC", benchmark_concat_incr>()) -NONIUS_BENCHMARK("i/flex_s/GC", benchmark_concat_incr>()) -NONIUS_BENCHMARK("i/flex/5B", benchmark_concat_incr>()) -NONIUS_BENCHMARK("i/flex/UN", benchmark_concat_incr>()) - -NONIUS_BENCHMARK("m/flex/GC", benchmark_concat_incr_mut>()) -NONIUS_BENCHMARK("m/flex_s/GC", benchmark_concat_incr_mut>()) diff --git a/third_party/immer/benchmark/vector/misc/drop.cpp b/third_party/immer/benchmark/vector/misc/drop.cpp deleted file mode 100644 index c2ca48390b13..000000000000 --- a/third_party/immer/benchmark/vector/misc/drop.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/drop.hpp" - -#include -#include -#include -#include -#include - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_drop_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_drop_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("l/librrb", benchmark_drop_lin_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("l/librrb/F", benchmark_drop_lin_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb", benchmark_drop_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_drop_mut_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("flex/4B", benchmark_drop>()) -NONIUS_BENCHMARK("flex/5B", benchmark_drop>()) -NONIUS_BENCHMARK("flex/6B", benchmark_drop>()) -NONIUS_BENCHMARK("flex/GC", benchmark_drop>()) -NONIUS_BENCHMARK("flex/NO", benchmark_drop>()) -NONIUS_BENCHMARK("flex/UN", benchmark_drop>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_drop>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_drop, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_drop, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_drop, push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_drop, push_front_fn>()) - -NONIUS_BENCHMARK("l/flex/5B", benchmark_drop_lin>()) -NONIUS_BENCHMARK("l/flex/GC", benchmark_drop_lin>()) -NONIUS_BENCHMARK("l/flex/NO", benchmark_drop_lin>()) -NONIUS_BENCHMARK("l/flex/UN", benchmark_drop_lin>()) -NONIUS_BENCHMARK("l/flex/F/5B", benchmark_drop_lin, push_front_fn>()) - -NONIUS_BENCHMARK("m/flex/5B", benchmark_drop_move>()) -NONIUS_BENCHMARK("m/flex/GC", benchmark_drop_move>()) -NONIUS_BENCHMARK("m/flex/NO", benchmark_drop_move>()) -NONIUS_BENCHMARK("m/flex/UN", benchmark_drop_move>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_drop_move, push_front_fn>()) - -NONIUS_BENCHMARK("t/flex/5B", benchmark_drop_mut>()) -NONIUS_BENCHMARK("t/flex/GC", benchmark_drop_mut>()) -NONIUS_BENCHMARK("t/flex/NO", benchmark_drop_mut>()) -NONIUS_BENCHMARK("t/flex/UN", benchmark_drop_mut>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_drop_mut, push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/misc/push-front.cpp b/third_party/immer/benchmark/vector/misc/push-front.cpp deleted file mode 100644 index 48b98c8ee9b1..000000000000 --- a/third_party/immer/benchmark/vector/misc/push-front.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push_front.hpp" - -#include - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_push_front_librrb) -#endif -NONIUS_BENCHMARK("flex/4B", bechmark_push_front>()) -NONIUS_BENCHMARK("flex/5B", bechmark_push_front>()) -NONIUS_BENCHMARK("flex/6B", bechmark_push_front>()) -NONIUS_BENCHMARK("flex/GC", bechmark_push_front>()) -NONIUS_BENCHMARK("flex_s/GC", bechmark_push_front>()) -NONIUS_BENCHMARK("flex/NO", bechmark_push_front>()) -NONIUS_BENCHMARK("flex/UN", bechmark_push_front>()) diff --git a/third_party/immer/benchmark/vector/misc/push.cpp b/third_party/immer/benchmark/vector/misc/push.cpp deleted file mode 100644 index 98f57600bd78..000000000000 --- a/third_party/immer/benchmark/vector/misc/push.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" - -#include -#include -#include -#include - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include -#endif - -#include -#include -#include - -#include -#include -#include - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include -#endif - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_push_librrb) -NONIUS_BENCHMARK("t/librrb", benchmark_push_mut_librrb) -#endif - -NONIUS_BENCHMARK("std::vector", benchmark_push_mut_std>()) -NONIUS_BENCHMARK("std::list", benchmark_push_mut_std>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_push_move>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_push_move>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_push_move>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_push_mut>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_push_mut>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_push_mut>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_push_mut>()) - -NONIUS_BENCHMARK("flex/5B", benchmark_push>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_push>()) - -NONIUS_BENCHMARK("vector/4B", benchmark_push>()) -NONIUS_BENCHMARK("vector/5B", benchmark_push>()) -NONIUS_BENCHMARK("vector/6B", benchmark_push>()) - -NONIUS_BENCHMARK("vector/GC", benchmark_push>()) -NONIUS_BENCHMARK("vector/NO", benchmark_push>()) -NONIUS_BENCHMARK("vector/UN", benchmark_push>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_push>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_push>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_push>()) - -NONIUS_BENCHMARK("dvektor/GC", benchmark_push>()) -NONIUS_BENCHMARK("dvektor/NO", benchmark_push>()) -NONIUS_BENCHMARK("dvektor/UN", benchmark_push>()) -#endif - -NONIUS_BENCHMARK("array", benchmark_push>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady", benchmark_push>()) -#endif diff --git a/third_party/immer/benchmark/vector/misc/take.cpp b/third_party/immer/benchmark/vector/misc/take.cpp deleted file mode 100644 index 78f0e958db4c..000000000000 --- a/third_party/immer/benchmark/vector/misc/take.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/take.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_take_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_take_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("l/librrb", benchmark_take_lin_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("l/librrb/F", benchmark_take_lin_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb", benchmark_take_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_take_mut_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("vector/4B", benchmark_take>()) -NONIUS_BENCHMARK("vector/5B", benchmark_take>()) -NONIUS_BENCHMARK("vector/6B", benchmark_take>()) -NONIUS_BENCHMARK("vector/GC", benchmark_take>()) -NONIUS_BENCHMARK("vector/NO", benchmark_take>()) -NONIUS_BENCHMARK("vector/UN", benchmark_take>()) -NONIUS_BENCHMARK("vector_s/GC", benchmark_take>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_take, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_take, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_take, push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_take, push_front_fn>()) - -NONIUS_BENCHMARK("l/vector/5B", benchmark_take_lin>()) -NONIUS_BENCHMARK("l/vector/GC", benchmark_take_lin>()) -NONIUS_BENCHMARK("l/vector/NO", benchmark_take_lin>()) -NONIUS_BENCHMARK("l/vector/UN", benchmark_take_lin>()) -NONIUS_BENCHMARK("l/flex/F/5B", benchmark_take_lin, push_front_fn>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_take_move>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_take_move>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_take_move>()) -NONIUS_BENCHMARK("m/vector/UN", benchmark_take_move>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_take_move, push_front_fn>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_take_mut>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_take_mut>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_take_mut>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_take_mut>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_take_mut, push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/paper/access.cpp b/third_party/immer/benchmark/vector/paper/access.cpp deleted file mode 100644 index db677a1adb80..000000000000 --- a/third_party/immer/benchmark/vector/paper/access.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" -#include -#include - -NONIUS_BENCHMARK("idx owrs", benchmark_access_idx>()) -NONIUS_BENCHMARK("idx librrb", benchmark_access_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("idx relaxed owrs", benchmark_access_idx,push_front_fn>()) -NONIUS_BENCHMARK("idx relaxed librrb", benchmark_access_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("idx std::vector", benchmark_access_idx_std>()) -NONIUS_BENCHMARK("idx chunkedseq32", benchmark_access_idx_std>()) -NONIUS_BENCHMARK("idx chunkedseq", benchmark_access_idx_std>()) - -NONIUS_BENCHMARK("iter orws", benchmark_access_iter>()) -NONIUS_BENCHMARK("iter relaxed orws", benchmark_access_iter,push_front_fn>()) -NONIUS_BENCHMARK("iter chunkedseq32", benchmark_access_iter_std>()) -NONIUS_BENCHMARK("iter chunkedseq", benchmark_access_iter_std>()) - -NONIUS_BENCHMARK("reduce owrs", benchmark_access_reduce>()) -NONIUS_BENCHMARK("reduce relaxed owrs", benchmark_access_reduce,push_front_fn>()) -NONIUS_BENCHMARK("reduce chunkedseq32", benchmark_access_reduce_chunkedseq>()) -NONIUS_BENCHMARK("reduce chunkedseq", benchmark_access_reduce_chunkedseq>()) -NONIUS_BENCHMARK("reduce std::vector", benchmark_access_iter_std>()) -NONIUS_BENCHMARK("reduce std::list", benchmark_access_iter_std>()) diff --git a/third_party/immer/benchmark/vector/paper/assoc-random.cpp b/third_party/immer/benchmark/vector/paper/assoc-random.cpp deleted file mode 100644 index becd4dc0c5b4..000000000000 --- a/third_party/immer/benchmark/vector/paper/assoc-random.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include -#include -#include - -NONIUS_BENCHMARK("ours/basic", benchmark_assoc_random>()) -NONIUS_BENCHMARK("ours/safe", benchmark_assoc_random>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_assoc_random>()) -NONIUS_BENCHMARK("ours/gc", benchmark_assoc_random>()) -NONIUS_BENCHMARK("librrb", benchmark_assoc_random_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("relaxed ours/basic", benchmark_assoc_random,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/safe", benchmark_assoc_random,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/unsafe", benchmark_assoc_random,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/gc", benchmark_assoc_random,push_front_fn>()) -NONIUS_BENCHMARK("relaxed librrb", benchmark_assoc_random_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_assoc_mut_random>()) -NONIUS_BENCHMARK("transient librrb", benchmark_assoc_mut_random_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient relaxed ours/basic", benchmark_assoc_mut_random,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/safe", benchmark_assoc_mut_random,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/unsafe", benchmark_assoc_mut_random,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/gc", benchmark_assoc_mut_random,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed librrb", benchmark_assoc_mut_random_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient std::vector", benchmark_assoc_random_std>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_assoc_random_std>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_assoc_random_std>()) diff --git a/third_party/immer/benchmark/vector/paper/assoc.cpp b/third_party/immer/benchmark/vector/paper/assoc.cpp deleted file mode 100644 index fe682ce74934..000000000000 --- a/third_party/immer/benchmark/vector/paper/assoc.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include -#include -#include - -NONIUS_BENCHMARK("ours/basic", benchmark_assoc>()) -NONIUS_BENCHMARK("ours/safe", benchmark_assoc>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_assoc>()) -NONIUS_BENCHMARK("ours/gc", benchmark_assoc>()) -NONIUS_BENCHMARK("librrb", benchmark_assoc_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("relaxed ours/basic", benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/safe", benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/unsafe", benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/gc", benchmark_assoc,push_front_fn>()) -NONIUS_BENCHMARK("relaxed librrb", benchmark_assoc_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_assoc_mut>()) -NONIUS_BENCHMARK("transient librrb", benchmark_assoc_mut_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient relaxed ours/basic", benchmark_assoc_mut,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/safe", benchmark_assoc_mut,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/unsafe", benchmark_assoc_mut,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/gc", benchmark_assoc_mut,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed librrb", benchmark_assoc_mut_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient std::vector", benchmark_assoc_std>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_assoc_std>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_assoc_std>()) diff --git a/third_party/immer/benchmark/vector/paper/concat.cpp b/third_party/immer/benchmark/vector/paper/concat.cpp deleted file mode 100644 index af9b3d20eda5..000000000000 --- a/third_party/immer/benchmark/vector/paper/concat.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" -#include -#include -#include - -NONIUS_BENCHMARK("ours/basic", benchmark_concat_incr>()) -NONIUS_BENCHMARK("ours/safe", benchmark_concat_incr>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_concat_incr>()) -NONIUS_BENCHMARK("ours/gc", benchmark_concat_incr>()) -NONIUS_BENCHMARK("librrb", benchmark_concat_incr_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient ours/gc", benchmark_concat_incr_mut>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_concat_incr_chunkedseq>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_concat_incr_chunkedseq>()) diff --git a/third_party/immer/benchmark/vector/paper/push.cpp b/third_party/immer/benchmark/vector/paper/push.cpp deleted file mode 100644 index 7c467985bb3b..000000000000 --- a/third_party/immer/benchmark/vector/paper/push.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" -#include -#include -#include - -NONIUS_BENCHMARK("ours/basic", benchmark_push>()) -NONIUS_BENCHMARK("ours/safe", benchmark_push>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_push>()) -NONIUS_BENCHMARK("ours/gc", benchmark_push>()) -NONIUS_BENCHMARK("librrb", benchmark_push_librrb) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_push_mut>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_push_mut>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_push_mut>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_push_mut>()) -NONIUS_BENCHMARK("transient librrb", benchmark_push_mut_librrb) -NONIUS_BENCHMARK("transient std::vector", benchmark_push_mut_std>()) -NONIUS_BENCHMARK("transient std::list", benchmark_push_mut_std>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_push_mut_std>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_push_mut_std>()) diff --git a/third_party/immer/benchmark/vector/push.hpp b/third_party/immer/benchmark/vector/push.hpp deleted file mode 100644 index 83f128c8fcc6..000000000000 --- a/third_party/immer/benchmark/vector/push.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template -auto benchmark_push_mut_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return v; - }); - }; -} - -template -auto benchmark_push_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}.transient(); - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return v; - }); - }; -} - -template -auto benchmark_push_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = std::move(v).push_back(i); - return v; - }); - }; -} - -template -auto benchmark_push() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - if (n > get_limit{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(i); - return v; - }); - }; -} - -auto benchmark_push_librrb(nonius::chronometer meter) -{ - auto n = meter.param(); - - measure(meter, [&] { - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) - v = rrb_push(v, reinterpret_cast(i)); - return v; - }); -} - -auto benchmark_push_mut_librrb(nonius::chronometer meter) -{ - auto n = meter.param(); - - measure(meter, [&] { - auto v = rrb_to_transient(rrb_create()); - for (auto i = 0u; i < n; ++i) - v = transient_rrb_push(v, reinterpret_cast(i)); - return v; - }); -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/push_front.hpp b/third_party/immer/benchmark/vector/push_front.hpp deleted file mode 100644 index 25ccbab0f9a6..000000000000 --- a/third_party/immer/benchmark/vector/push_front.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template -auto bechmark_push_front() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = v.push_front(i); - return v; - }); - }; -} - -auto benchmark_push_front_librrb(nonius::chronometer meter) -{ - auto n = meter.param(); - - measure(meter, [&] { - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - auto f = rrb_push(rrb_create(), - reinterpret_cast(i)); - v = rrb_concat(f, v); - } - return v; - }); -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/take.hpp b/third_party/immer/benchmark/vector/take.hpp deleted file mode 100644 index bce5aceb0072..000000000000 --- a/third_party/immer/benchmark/vector/take.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template -auto benchmark_take() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - (void) v.take(i); - }); - }; -} - -template -auto benchmark_take_lin() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = r.take(i); - return r; - }); - }; -} - -template -auto benchmark_take_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = std::move(r).take(i); - return r; - }); - }; -} - -template -auto benchmark_take_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param(); - - auto vv = Vektor{}; - for (auto i = 0u; i < n; ++i) - vv = PushFn{}(std::move(vv), i); - - measure(meter, [&] { - auto v = vv.transient(); - for (auto i = n; i > 0; --i) - (void) v.take(i); - }); - }; -} - -template -auto benchmark_take_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - rrb_slice(v, 0, i); - }); - }; -} - -template -auto benchmark_take_lin_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure( - meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = rrb_slice(r, 0, i); - return r; - }); - }; -} - -template -auto benchmark_take_mut_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param(); - auto v = make(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = n; i > 0; --i) - r = transient_rrb_slice(r, 0, i); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/cmake/FindBoehmGC.cmake b/third_party/immer/cmake/FindBoehmGC.cmake deleted file mode 100644 index bdb7240e6d8c..000000000000 --- a/third_party/immer/cmake/FindBoehmGC.cmake +++ /dev/null @@ -1,108 +0,0 @@ -# - Try to find Boehm GC -# Once done, this will define -# -# BOEHM_GC_FOUND - system has Boehm GC -# BOEHM_GC_INCLUDE_DIR - the Boehm GC include directories -# BOEHM_GC_LIBRARIES - link these to use Boehm GC -# -# Copyright (c) 2010-2015 Takashi Kato -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# $Id: $ -# - -# CMake module to find Boehm GC - -# use pkg-config if available -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_BDW_GC QUIET bdw-gc) - -# try newer one first in case of gc.h is overwritten. -FIND_PATH(BOEHM_GC_INCLUDE_DIR gc/gc.h - HINTS ${PC_BDW_GC_INCLUDEDIR} ${PC_BDW_GC_INCLUDE_DIRS}) - -IF (NOT BOEHM_GC_INCLUDE_DIR) - FIND_PATH(BOEHM_GC_INCLUDE_DIR gc.h - HINTS ${PC_BDW_GC_INCLUDEDIR} ${PC_BDW_GC_INCLUDE_DIRS}) - IF (BOEHM_GC_INCLUDE_DIR) - SET(HAVE_GC_H TRUE) - ENDIF() -ELSE() - SET(HAVE_GC_GC_H TRUE) -ENDIF() - -# For FreeBSD we need to use gc-threaded -IF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - # checks if 'gc' supports 'GC_get_parallel' and if it does - # then use it - INCLUDE(${CMAKE_ROOT}/Modules/CheckCSourceCompiles.cmake) - # not sure if this links properly... - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES gc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - MESSAGE(STATUS "GC library ${BOEHM_GC_LIBRARIES}") - SET(CMAKE_REQUIRED_LIBRARIES "gc") - SET(CMAKE_REQUIRED_DEFINITIONS "-DGC_THREADS") - SET(CMAKE_REQUIRED_INCLUDES "${BOEHM_GC_INCLUDE_DIR}") - SET(CMAKE_REQUIRED_FLAGS "-L${PC_BDW_GC_LIBRARY_DIRS}") - MESSAGE(STATUS "Boehm GC include dir: ${CMAKE_REQUIRED_INCLUDES}") - CHECK_C_SOURCE_RUNS( - "#include -int main() { -int i= GC_get_parallel(); -return 0; -} -" GC_GET_PARALLEL_WORKS) - IF (NOT GC_GET_PARALLEL_WORKS) - MESSAGE(STATUS "Try gc-threaded") - - # bdw-gc-threaded is the proper name for FreeBSD pkg-config - PKG_CHECK_MODULES(PC_BDW_GC_THREADED bdw-gc-threaded) - FIND_LIBRARY(BOEHM_GC_THREADED_LIBRARIES NAMES gc-threaded - HINTS ${PC_BDW_GC_THREADED_LIBDIR} ${PC_BDW_GC_THREADED_THREADED_DIRS}) - - MESSAGE(STATUS "GC threaded library ${BOEHM_GC_THREADED_LIBRARIES}") - IF (BOEHM_GC_THREADED_LIBRARIES) - # OK just use it - SET(BOEHM_GC_LIBRARIES "${BOEHM_GC_THREADED_LIBRARIES}") - ENDIF() - ENDIF() -ELSE() - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES gc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - # OpenSolaris uses bgc as Boehm GC runtime in its package manager. - # so try it - IF (NOT BOEHM_GC_LIBRARIES) - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES bgc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - ENDIF() -ENDIF() - -MESSAGE(STATUS "Found GC library: ${BOEHM_GC_LIBRARIES}") - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Boehm_GC DEFAULT_MSG - BOEHM_GC_LIBRARIES BOEHM_GC_INCLUDE_DIR) - -MARK_AS_ADVANCED(BOEHM_GC_LIBRARIES BOEHM_GC_INCLUDE_DIR) diff --git a/third_party/immer/cmake/FindGuile.cmake b/third_party/immer/cmake/FindGuile.cmake deleted file mode 100644 index 2b8781c48f48..000000000000 --- a/third_party/immer/cmake/FindGuile.cmake +++ /dev/null @@ -1,326 +0,0 @@ -#[[.rst -# -# FindGuile -# --------- -# Find the development libraries for Guile. -# -# Exported Vars -# ~~~~~~~~~~~~~ -# -# .. variable:: Guile_FOUND -# -# Set to *true* if Guile was found. -# -# .. variable:: Guile_INCLUDE_DIRS -# -# A list of include directories. -# -# .. variable:: Guile_LIBRARIES -# -# A list of libraries needed to build you project. -# -# .. variable:: Guile_VERSION_STRING -# -# Guile full version. -# -# .. variable:: Guile_VERSION_MAJOR -# -# Guile major version. -# -# .. variable:: Guile_VERSION_MINOR -# -# Guile minor version. -# -# .. variable:: Guile_VERSION_PATCH -# -# Guile patch version. -# -# .. variable:: Guile_EXECUTABLE -# -# Guile executable (optional). -# -# .. variable:: Guile_CONFIG_EXECUTABLE -# -# Guile configuration executable (optional). -# -# .. variable:: Guile_ROOT_DIR -# -# Guile installation root dir (optional). -# -# .. variable:: Guile_SITE_DIR -# -# Guile installation module site dir (optional). -# -# .. variable:: Guile_EXTENSION_DIR -# -# Guile installation extension dir (optional). -# -# Control VARS -# ~~~~~~~~~~~~ -# :envvar:`Guile_ROOT_DIR` -# -# Use this variable to provide hints to :filename:`find_{*}` commands, -# you may pass it to :command:`cmake` or set the environtment variable. -# -# .. code-block:: cmake -# -# % cmake . -Bbuild -DGuile_ROOT_DIR= -# -# # or -# % export Guile_ROOT_DIR=; -# % cmake . -Bbuild -# -# # or -# % Guile_ROOT_DIR= cmake . -Bbuild -# -# -#]] - - -#[[.rst -# -# Copyright © 2016, Edelcides Gonçalves -# -# Permission to use, copy, modify, and/or distribute this software for -# any purpose with or without fee is hereby granted, provided that the -# above copyright notice and this permission notice appear in all -# copies. -# -# *THE SOFTWARE IS PROVIDED* **AS IS** *AND ISC DISCLAIMS ALL -# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE -# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE*. -# -# This file is not part of CMake -# -#]] - - -include (SelectLibraryConfigurations) -include (FindPackageHandleStandardArgs) - -function (_guile_find_component_include_dir component header) - find_path ("${component}_INCLUDE_DIR" - ${header} - HINTS - "${GUile_ROOT_DIR}" - ENV Guile_ROOT_DIR - PATH_SUFFIXES - Guile guile Guile-2.0 guile-2.0 Guile/2.0 guile/2.0 GC - gc) - - set ("${component}_INCLUDE_DIR" "${${component}_INCLUDE_DIR}" - PARENT_SCOPE) -endfunction () - -function (_guile_find_component_library component_name component) - - find_library ("${component_name}_LIBRARY_RELEASE" - NAMES "${component}" "${component}-2.0" - HINTS - "${GUile_ROOT_DIR}" - ENV Guile_ROOT_DIR - PATHS - /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} - /usr/lib64/${CMAKE_LIBRARY_ARCHITECTURE} - /usr/lib32/${CMAKE_LIBRARY_ARCHITECTURE}) - - if (${component_name}_LIBRARY_RELEASE) - select_library_configurations (${component_name}) - set ("${component_name}_LIBRARY_RELEASE" - "${${component_name}_LIBRARY_RELEASE}" PARENT_SCOPE) - set ("${component_name}_LIBRARY" - "${${component_name}_LIBRARY}" PARENT_SCOPE) - set ("${component_name}_LIBRARIES" - "${${component_name}_LIBRARIES}" PARENT_SCOPE) - endif () -endfunction () - -function (_guile_find_version_2 header_file macro_name) - file (STRINGS "${header_file}" _VERSION - REGEX "#define[\t ]+${macro_name}[\t ]+[0-9]+") - - if (_VERSION) - string (REGEX REPLACE - ".*#define[\t ]+${macro_name}[\t ]+([0-9]+).*" - "\\1" _VERSION_VALUE "${_VERSION}") - if ("${_VERSION}" STREQUAL "${_VERSION_VALUE}") - set (_VERSION_FOUND 0 PARENT_SCOPE) - else () - set (_VERSION_FOUND 1 PARENT_SCOPE) - set (_VERSION "${_VERSION_VALUE}" PARENT_SCOPE) - endif () - else () - set (_VERSION_FOUND 0 PARENT_SCOPE) - endif () -endfunction () - - -##### Entry Point ##### - -set (Guile_FOUND) -set (Guile_INCLUDE_DIRS) -set (Guile_LIBRARIES) -set (Guile_VERSION_STRING) -set (Guile_VERSION_MAJOR) -set (Guile_VERSION_MINOR) -set (Guile_VERSION_PATCH) -set (Guile_EXECUTABLE) - -_guile_find_component_include_dir (Guile "libguile.h") -if (Guile_INCLUDE_DIR) - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MAJOR_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_MAJOR "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MAJOR_VERSION.") - endif () - - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MINOR_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_MINOR "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MINOR_VERSION.") - endif () - - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MICRO_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_PATCH "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MICRO_VERSION.") - endif () - set (Guile_VERSION_STRING "${Guile_VERSION_MAJOR}.${Guile_VERSION_MINOR}.${Guile_VERSION_PATCH}") - - unset (_VERSION_FOUND) - unset (_VERSION) -endif () - -_guile_find_component_include_dir (Guile_GC "gc.h") -_guile_find_component_library (Guile guile) -_guile_find_component_library (Guile_GC gc) - -find_program (Guile_EXECUTABLE - guile - DOC "Guile executable.") - -if (Guile_EXECUTABLE) - execute_process (COMMAND ${Guile_EXECUTABLE} --version - RESULT_VARIABLE _status - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE) - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+([0-9]+)\\..*" "\\1" - _guile_ver_major "${_output}") - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+[0-9]+\\.([0-9]+).*" "\\1" - _guile_ver_minor "${_output}") - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" - _guile_ver_patch "${_output}") - - set (_version "${_guile_ver_major}.${_guile_ver_minor}.${_guile_ver_patch}") - - if (NOT Guile_FIND_QUIETLY) - if (NOT Guile_VERSION_STRING STREQUAL _version) - message (WARNING "FindGuile: Versions provided by library differs from the one provided by executable.") - endif () - - if (NOT _status STREQUAL "0") - message (WARNING "FindGuile: guile (1) process exited abnormally.") - endif () - endif () - - unset (_version) - unset (_status) - unset (_version) - unset (_guile_ver_major) - unset (_guile_ver_minor) - unset (_guile_ver_patch) -endif () - -find_package_handle_standard_args (GC - "FindGuile: Failed to find dependency GC." - Guile_GC_INCLUDE_DIR - Guile_GC_LIBRARY - Guile_GC_LIBRARIES - Guile_GC_LIBRARY_RELEASE) - -find_package_handle_standard_args (Guile - REQUIRED_VARS - Guile_INCLUDE_DIR - Guile_LIBRARY - Guile_LIBRARIES - Guile_LIBRARY_RELEASE - GC_FOUND - VERSION_VAR Guile_VERSION_STRING) - -if (Guile_FOUND) - list (APPEND Guile_INCLUDE_DIRS "${Guile_INCLUDE_DIR}" - "${Guile_GC_INCLUDE_DIR}") - - if (NOT TARGET Guile::Library AND NOT TARGET GC::Library) - add_library (Guile::GC::Library UNKNOWN IMPORTED) - set_property (TARGET Guile::GC::Library APPEND - PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - - set_target_properties (Guile::GC::Library - PROPERTIES - INTERFACE_INCLUDE_DIRS - "${Guile_GC_INCLUDE_DIR}" - IMPORTED_LOCATION - "${Guile_GC_LIBRARY}" - IMPORTED_LOCATION_RELEASE - "${Guile_GC_LIBRARY_RELEASE}") - - add_library (Guile::Library UNKNOWN IMPORTED) - set_property (TARGET Guile::Library APPEND - PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_property (TARGET Guile::Library APPEND - PROPERTY - INTERFACE_LINK_LIBRARIES - Guile::GC::Library) - - set_target_properties (Guile::Library - PROPERTIES - INTERFACE_INCLUDE_DIRSr - "${Guile_INCLUDE_DIR}" - IMPORTED_LOCATION "${Guile_LIBRARY}" - IMPORTED_LOCATION_RELEASE - "${Guile_LIBRARY_RELEASE}") - - set (Guile_LIBRARIES Guile::Library Guile::GC::Library) - endif () -endif () - -find_program(Guile_CONFIG_EXECUTABLE - NAMES guile-config - DOC "Guile configutration binary") - -if (Guile_CONFIG_EXECUTABLE) - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info prefix - OUTPUT_VARIABLE Guile_ROOT_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info sitedir - OUTPUT_VARIABLE Guile_SITE_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info extensiondir - OUTPUT_VARIABLE Guile_EXTENSION_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif () - -mark_as_advanced (Guile_EXECUTABLE - Guile_INCLUDE_DIR - Guile_LIBRARY - Guile_LIBRARY_RELEASE - Guile_GC_INCLUDE_DIR - Guile_GC_LIBRARY - Guile_GC_LIBRARY_RELEASE) diff --git a/third_party/immer/cmake/FindRRB.cmake b/third_party/immer/cmake/FindRRB.cmake deleted file mode 100644 index 86b552f86e43..000000000000 --- a/third_party/immer/cmake/FindRRB.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# - Try to find c-rrb -# Once done, this will define -# -# RRB_FOUND - system has RRB -# RRB_INCLUDE_DIR - the RRB include directories -# RRB_LIBRARIES - link these to use RRB - -find_path(RRB_INCLUDE_DIR rrb.h) -find_library(RRB_LIBRARIES NAMES rrb librrb) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - RRB DEFAULT_MSG RRB_LIBRARIES RRB_INCLUDE_DIR) - -mark_as_advanced(RRB_INCLUDE_DIR RRB_LIBRARIES) diff --git a/third_party/immer/cmake/ImmerUtils.cmake b/third_party/immer/cmake/ImmerUtils.cmake deleted file mode 100644 index 2af63ff6061d..000000000000 --- a/third_party/immer/cmake/ImmerUtils.cmake +++ /dev/null @@ -1,24 +0,0 @@ - -function(immer_target_name_for out_target out_file file) - get_filename_component(_extension ${_file} EXT) - - file(RELATIVE_PATH _relative ${PROJECT_SOURCE_DIR} ${file}) - string(REPLACE "${_extension}" "" _name ${_relative}) - string(REGEX REPLACE "/" "-" _name ${_name}) - set(${out_target} "${_name}" PARENT_SCOPE) - - file(RELATIVE_PATH _relative ${CMAKE_CURRENT_LIST_DIR} ${file}) - string(REPLACE "${_extension}" "" _name ${_relative}) - string(REGEX REPLACE "/" "-" _name ${_name}) - set(${out_file} "${_name}" PARENT_SCOPE) -endfunction() - -function(immer_canonicalize_cmake_booleans) - foreach(var ${ARGN}) - if(${var}) - set(${var} 1 PARENT_SCOPE) - else() - set(${var} 0 PARENT_SCOPE) - endif() - endforeach() -endfunction() diff --git a/third_party/immer/codecov.yml b/third_party/immer/codecov.yml deleted file mode 100644 index ab21ebea5d98..000000000000 --- a/third_party/immer/codecov.yml +++ /dev/null @@ -1,2 +0,0 @@ -ignore: - - tools diff --git a/third_party/immer/default.nix b/third_party/immer/default.nix deleted file mode 100644 index f9225f9fd713..000000000000 --- a/third_party/immer/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, lib, ... }: - -pkgs.llvmPackages.libcxxStdenv.mkDerivation rec { - name = "immer-git"; - version = "git"; - src = ./.; - nativeBuildInputs = [ pkgs.cmake ]; - dontBuild = true; - meta = with lib; { - homepage = "https://github.com/arximboldi/immer"; - description = "Postmodern immutable data structures for C++"; - license = licenses.boost; - }; -} diff --git a/third_party/immer/doc/CMakeLists.txt b/third_party/immer/doc/CMakeLists.txt deleted file mode 100644 index 0b3d85c6ac1a..000000000000 --- a/third_party/immer/doc/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ - -# Targets -# ======= - -add_custom_target(doxygen - COMMAND doxygen doxygen.config - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") - -add_custom_target(docs - COMMAND make html - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") -add_dependencies(docs doxygen) - -set(immer_ssh_method - ssh -p 5488 - -o StrictHostKeyChecking=no - -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key) - -add_custom_target(upload-docs - COMMAND - rsync -av -e \"${immer_ssh_method}\" - ${CMAKE_SOURCE_DIR}/doc/_build/html/* - raskolnikov@sinusoid.es:public/immer/) diff --git a/third_party/immer/doc/Makefile b/third_party/immer/doc/Makefile deleted file mode 100644 index 101addd4ef25..000000000000 --- a/third_party/immer/doc/Makefile +++ /dev/null @@ -1,226 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " epub3 to make an epub3" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - @echo " dummy to check syntax errors of document sources" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - bash sphinx-html-hack.bash - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/immer.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/immer.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/immer" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/immer" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: epub3 -epub3: - $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 - @echo - @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -.PHONY: dummy -dummy: - $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy - @echo - @echo "Build finished. Dummy builder generates no files." diff --git a/third_party/immer/doc/_static/logo-black.svg b/third_party/immer/doc/_static/logo-black.svg deleted file mode 100644 index 370e047c4b30..000000000000 --- a/third_party/immer/doc/_static/logo-black.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - immer - - - - diff --git a/third_party/immer/doc/_static/logo-front.svg b/third_party/immer/doc/_static/logo-front.svg deleted file mode 100644 index b56393b9b1e1..000000000000 --- a/third_party/immer/doc/_static/logo-front.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - immer - - - - diff --git a/third_party/immer/doc/_static/logo.svg b/third_party/immer/doc/_static/logo.svg deleted file mode 100644 index 64bff0dde807..000000000000 --- a/third_party/immer/doc/_static/logo.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - immer - - - - diff --git a/third_party/immer/doc/_static/patreon.svg b/third_party/immer/doc/_static/patreon.svg deleted file mode 100644 index a8cc33975b21..000000000000 --- a/third_party/immer/doc/_static/patreon.svg +++ /dev/null @@ -1,120 +0,0 @@ - - - -image/svg+xmlsupportsupportsupport us on - \ No newline at end of file diff --git a/third_party/immer/doc/_static/sinusoidal-badge.svg b/third_party/immer/doc/_static/sinusoidal-badge.svg deleted file mode 100644 index 0282a2f7a41f..000000000000 --- a/third_party/immer/doc/_static/sinusoidal-badge.svg +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - quality libre software by sinusoidal engineering - - - - - - - - - - - - - - - - diff --git a/third_party/immer/doc/algorithms.rst b/third_party/immer/doc/algorithms.rst deleted file mode 100644 index f7de519c05d9..000000000000 --- a/third_party/immer/doc/algorithms.rst +++ /dev/null @@ -1,28 +0,0 @@ - -Algorithms -========== - -This module provides overloads of standard algorithms that leverage -the internal structure of the immutable containers to provide faster -iteration. These are drop-in replacements of the respective STL -algorithms that can be a few times faster when applied on immutable -sequences. - -For further convenience they can be passed in just a container where -the standard library algorithms require being passed in two iterators. - -.. note:: - - They are a similar idea to `structure-aware iterators`_ - but implemented using higher order functions in order to support - structures of any depth. The downside is that this sometimes - causes the compiler to generate bigger executable files. - -.. _structure-aware iterators: https://www.youtube.com/watch?v=T3oA3zAMH9M - - ------ - -.. doxygengroup:: algorithm - :project: immer - :content-only: diff --git a/third_party/immer/doc/conf.py b/third_party/immer/doc/conf.py deleted file mode 100644 index 3c32cc505ba3..000000000000 --- a/third_party/immer/doc/conf.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# -# immer documentation build configuration file, created by -# sphinx-quickstart on Thu Oct 27 18:10:24 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.mathjax', - 'breathe', -] - -breathe_projects = { "immer": "_doxygen/xml" } -breathe_default_project = "immer" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -from recommonmark.parser import CommonMarkParser -from recommonmark.transform import AutoStructify -source_parsers = { '.md': CommonMarkParser, } -source_suffix = ['.rst', '.md'] - -def setup(app): - app.add_config_value('recommonmark_config', { - 'enable_eval_rst': True, - }, True) - app.add_transform(AutoStructify) - -# The encoding of source files. -# -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'immer' -copyright = u'2016, 2017 Juan Pedro Bolivar Puente' -author = u'Juan Pedro Bolivar Puente' - -raw_enabled = True - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = u'0.0.0' -# The full version, including alpha/beta/rc tags. -release = u'0.0.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# - -import sys -import os.path -sys.path.append(os.path.join(os.path.dirname(__file__), - '../tools/sinusoidal-sphinx-theme')) - -import sinusoidal_sphinx_theme -html_theme_path = sinusoidal_sphinx_theme.html_theme_path() -html_theme = 'sinusoidal_sphinx_theme' -extensions.append("sinusoidal_sphinx_theme") -html_theme_options = { - "project_nav_name": "immer", - "github_link" : "https://github.com/arximboldi/immer", -} - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. -# " v documentation" by default. -# -# html_title = u'immer v0.0.0' - -# A shorter title for the navigation bar. Default is the same as html_title. -# -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# -html_logo = '_static/logo-black.svg' - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%b %d, %Y'. -# -# html_last_updated_fmt = None - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# -# html_additional_pages = {} - -# If false, no module index is generated. -# -# html_domain_indices = True - -# If false, no index is generated. -# -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -# -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'immerdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'immer.tex', u'immer Documentation', - u'Juan Pedro Bolivar Puente', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# It false, will not define \strong, \code, itleref, \crossref ... but only -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added -# packages. -# -# latex_keep_old_macro_names = True - -# If false, no module index is generated. -# -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'immer', u'immer Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -# -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'immer', u'immer Documentation', - author, 'immer', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project -epub_author = author -epub_publisher = author -epub_copyright = copyright - -# The basename for the epub file. It defaults to the project name. -# epub_basename = project - -# The HTML theme for the epub output. Since the default themes are not -# optimized for small screen space, using the same theme for HTML and epub -# output is usually not wise. This defaults to 'epub', a theme designed to save -# visual space. -# -# epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or 'en' if the language is not set. -# -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# -# epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -# -# epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_pre_files = [] - -# HTML files that should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -# -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# -# epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -# -# epub_tocscope = 'default' - -# Fix unsupported image types using the Pillow. -# -# epub_fix_images = False - -# Scale large images. -# -# epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# epub_show_urls = 'inline' - -# If false, no index is generated. -# -# epub_use_index = True diff --git a/third_party/immer/doc/containers.rst b/third_party/immer/doc/containers.rst deleted file mode 100644 index c6913ba4a5e5..000000000000 --- a/third_party/immer/doc/containers.rst +++ /dev/null @@ -1,50 +0,0 @@ -.. highlight:: c++ - -Containers -========== - -This section describes all the containers provided by the library. -Check the :ref:`design` section for a general discussion of these -containers and how to use them. - -box ---- - -.. doxygenclass:: immer::box - :members: - :undoc-members: - -array ------ - -.. doxygenclass:: immer::array - :members: - :undoc-members: - -vector ------- - -.. doxygenclass:: immer::vector - :members: - :undoc-members: - -flex_vector ------------ - -.. doxygenclass:: immer::flex_vector - :members: - :undoc-members: - -set ---- - -.. doxygenclass:: immer::set - :members: - :undoc-members: - -map ---- - -.. doxygenclass:: immer::map - :members: - :undoc-members: diff --git a/third_party/immer/doc/design.rst b/third_party/immer/doc/design.rst deleted file mode 100644 index 27d29e9e617a..000000000000 --- a/third_party/immer/doc/design.rst +++ /dev/null @@ -1,268 +0,0 @@ -.. _design: - -Design -====== - -This is a library of **immutable containers**. - -These containers have all their methods marked ``const``. Instead of -mutating them *in place*, they provide manipulation functions that -*return a new transformed value*, leaving the original value -unaltered. In the context of data-structures, this property of -preserving old values is called **persistence**. - -Most of these containers use data-structures in which these operations -can be done *efficiently*. In particular, not all data is copied when -a new value is produced. Instead, the new values may share, -internally, common data with other objects. We sometimes refer to -this property as **structural sharing**. This behaviour is -transparent to the user. - -Assigment ---------- - -We are sorry, we lied. These containers provide *one mutating -operation*: **assignment** --- i.e. ``operator=``. - -There is a good reason: without ``operator=`` everything becomes -complicated in C++. For example, one may not contain non-assignable -types in many standard containers, assignment would also be disabled -from your custom types holding immutable containers, and so on and so -forth. - -C++ is a multi-paradigm language with an imperative core. Thus, it is -built on the foundation that *variables* can be mutated --- -i.e. assigned to. We don't want to ride against this tide. What we -want to prevent is in-place *object* manipulation. Because of C++ -semantics, *variable* assignment is defined in terms of *object -mutation*, so we have to provide *this very particular mutating -operation*, but nothing else. Of course, you are free to mark your -variables ``const`` to completely forbid assignment. - -.. warning:: - - **Assignment is not thread safe**. When a *mutable* variable is - shared across multiple threads, protect access using some other - mechanism. - - For obvious reasons, all other methods, which are ``const``, are - thread-safe. It is safe to share *immutable* state across multiple - threads. - -To ``const`` or not to ``const`` --------------------------------- - -Many C++ programmers, influenced by functional programming, are trying -to escape the evils of mutability by using ``const`` whenever -possible. We also do it ourselves in many of our examples to -reinforce the property of immutability. - -While in general this is a good practice backed up with very good -intentions, it has one caveat: *it disables moveability*. It does so -even when ``std::move()`` is used. This makes sense, since moving from -an object may mutate it, and ``const``, my friends, prevents *all* -mutations. For example: - -.. literalinclude:: ../example/vector/move.cpp - :language: c++ - :start-after: move-bad/start - :end-before: move-bad/end - -One may think that the variable ``v`` is moved into the -``push_back()`` call. This is not the case, because the variable -``v`` is marked ``const``. Of course, one may enable the move by -removing it, as in: - -.. literalinclude:: ../example/vector/move.cpp - :language: c++ - :start-after: move-good/start - :end-before: move-good/end - -So, is it bad style then to use ``const`` as much as possible? I -wouldn't say so and it is advisable when ``std::move()`` is not used. -An alternative style is to not use ``const`` but adopt an `AAA-style -`_ (*Almost Always use Auto*). This way, it is easy to look for -mutations by looking for lines that contain ``=`` but no ``auto``. -Remember that when using our immutable containers ``operator=`` is the -only way to mutate a variable. - -.. _aaa: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ - -.. admonition:: Why does ``const`` prevent move semantics? - - For those adventurous into the grainy details C++, here is why. - ``std::move()`` does not move anything, it is just *a cast* from - normal *l-value* references (``T&``) to *r-value* reference - (``T&&``). This is, you pass it a variable, and it returns a - reference to its object disguised as an intermediate result. In - exchange, you promise not to do anything with this variable later - [#f1]_. It is the role of the thing that *receives the moved-from - value* (in the previous example, ``push_back``) to actually do - anything interesting with it --- for example, steal its contents - 😈. - - So if you pass a ``T&`` to ``std::move()`` you get a ``T&&`` and, - unsurprisingly, if you pass a ``const T&`` you get a ``const T&&``. - But the receivers of the moved-from value (like constructors or our - ``push_back()``) maybe be moved-into because they provide an - overload that expects ``T&&`` --- without the ``const``! Since a - ``const T&&`` can not be converted into a ``T&&``, the compiler - looks up for you another viable overload, and most often finds a - copy constructor or something alike that expects a ``const T&`` or - just ``T``, to which a ``const T&&`` can be converted. The code - compiles and works correctly, but it is less efficient than we - expected. Our call to ``std::move()`` was fruitless. - - .. [#f1] For the sake of completeness: it is actually allowed to do stuff - with the variable *after another value is assigned to it*. - -.. _move-semantics: - -Leveraging move semantics -------------------------- - -When using :ref:`reference counting` (which is the default) -mutating operations can often be faster when operating on *r-value -references* (temporaries and moved-from values). Note that this -removes *persistence*, since one can not access the moved-from value -anymore! However, this may be a good idea when doing a chain of -operations where the intermediate values are not important to us. - -For example, let's say we want to write a function that inserts all -integers in the range :math:`[first, last)` into an immutable vector. -From the point of view of the caller of the function, this function is -a *transaction*. Whatever intermediate vectors are generated inside -of it can be discarded since the caller can only see the initial -vector (the one passed in as argument) and the vector with *all* the -elements. We may write such function like this: - -.. literalinclude:: ../example/vector/iota-move.cpp - :language: c++ - :start-after: myiota/start - :end-before: myiota/end - -The intermediate values are *moved* into the next ``push_back()`` -call. They are going to be discarded anyways, this little -``std::move`` just makes the whole thing faster, letting ``push_back`` -mutate part of the internal data structure in place when possible. - -If you don't like this syntax, :doc:`transients` may be -used to obtain similar performance benefits. - -.. admonition:: Assigment guarantees - - From the language point of view, the only requirement on moved from - values is that they should still be destructible. We provide the - following two additional guarantees: - - - **It is valid to assign to a moved-from variable**. The variable - gets the assigned value and becomes usable again. This is the - behaviour of standard types. - - - **It is valid to assign a moved-from variable to itself**. For - most standard types this is *undefined behaviour*. However, for our - immutable containers types, expressions of the form ``v = - std::move(v)`` are well-defined. - -Recursive types ---------------- - -Most containers will fail to be instantiated with a type of unknown -size, this is, an *incomplete type*. This prevents using them for -building recursive types. The following code fails to compile: - -.. code-block:: c++ - - struct my_type - { - int data; - immer::vector children; - }; - -However, we can easily workaround this by using an ``immer::box`` to wrap -the elements in the vector, as in: - -.. code-block:: c++ - - struct my_type - { - int data; - immer::vector> children; - }; - -.. admonition:: Standard containers and incomplete types - - While the first example might seem to compile when using some - implementations of ``std::vector`` instead of ``immer::vector``, such - use is actually forbidden by the standard: - - **17.6.4.8** *Other functions (...)* 2. the effects are undefined in - the following cases: (...) In particular---if an incomplete type (3.9) - is used as a template argument when instantiating a template - component, unless specifically allowed for that component. - -.. _batch-update: -Efficient batch manipulations ------------------------------ - -Sometimes you may write a function that needs to do multiple changes -to a container. Like most code you write with this library, this -function is *pure*: it takes one container value in, and produces a -new container value out, no side-effects. - -Let's say we want to write a function that inserts all integers in the -range :math:`[first, last)` into an immutable vector: - -.. literalinclude:: ../example/vector/iota-slow.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end - -This function works as expected, but it is slower than necessary. -On every loop iteration, a new value is produced, just to be -forgotten in the next iteration. - -Instead, we can grab a mutable view on the value, a :ref:`transient`. -Then, we manipulate it *in-place*. When we are done with it, we -extract back an immutable value from it. The code now looks like -this: - -.. _iota-transient: - -.. literalinclude:: ../example/vector/iota-transient.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end - -Both conversions are :math:`O(1)`. Note that calling ``transient()`` -does not break the immutability of the variable it is called on. The -new mutable object will adopt its contents, but when a mutation is -performed, it will copy the data necessary using *copy on write*. -Subsequent manipulations may hit parts that have already been copied, -and these changes are done in-place. Because of this, it does not -make sense to use transients to do only one change. - -.. tip:: - - Note that :ref:`move semantics` can be used instead to - support a similar use-case. However, transients optimise updates - even when reference counting is disabled. - -.. _std-compat: -Standard library compatibility ------------------------------- - -While the immutable containers provide an interface that follows a -functional style, this is incompatible with what the standard library -algorithms sometimes expect. :ref:`transients` try to provide an -interface as similar as possible to similar standard library -containers. Thus, can also be used to interoperate with standard -library components. - -For example the :ref:`myiota() function above` may as -well be written using standard library tools: - -.. literalinclude:: ../example/vector/iota-transient-std.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end diff --git a/third_party/immer/doc/doxygen.config b/third_party/immer/doc/doxygen.config deleted file mode 100644 index b6002b8d8f07..000000000000 --- a/third_party/immer/doc/doxygen.config +++ /dev/null @@ -1,23 +0,0 @@ -PROJECT_NAME = "immer" -OUTPUT_DIRECTORY = _doxygen -GENERATE_LATEX = NO -GENERATE_MAN = NO -GENERATE_RTF = NO -GENERATE_HTML = NO -GENERATE_XML = YES -INPUT = \ - ../immer \ - ../immer/heap \ - ../immer/refcount \ - ../immer/transience -INCLUDE_PATH = .. -QUIET = YES - -JAVADOC_AUTOBRIEF = YES -ENABLE_PREPROCESSING = YES -MARKDOWN_SUPPORT = YES -MACRO_EXPANSION = YES - -ALIASES = "rst=\verbatim embed:rst:leading-asterisk\n" -ALIASES += "endrst=\n\endverbatim" -ALIASES += "rst{1}=\rst\1\endrst" diff --git a/third_party/immer/doc/guile.rst b/third_party/immer/doc/guile.rst deleted file mode 120000 index dfda6df878f4..000000000000 --- a/third_party/immer/doc/guile.rst +++ /dev/null @@ -1 +0,0 @@ -../extra/guile/README.rst \ No newline at end of file diff --git a/third_party/immer/doc/implementation.rst b/third_party/immer/doc/implementation.rst deleted file mode 100644 index 3bfdd9c2b812..000000000000 --- a/third_party/immer/doc/implementation.rst +++ /dev/null @@ -1,6 +0,0 @@ -Implementation overview -======================= - -.. image:: https://upload.wikimedia.org/wikipedia/commons/e/e6/%22Work_in_progress%22%2C_animated.gif - :alt: Work in Progress - :align: center diff --git a/third_party/immer/doc/index.rst b/third_party/immer/doc/index.rst deleted file mode 100644 index 311549c74bcd..000000000000 --- a/third_party/immer/doc/index.rst +++ /dev/null @@ -1,31 +0,0 @@ - -.. include:: ../README.rst - :end-before: include:index/end - -Contents --------- - -.. toctree:: - :caption: User Manual - :maxdepth: 3 - - introduction - design - containers - transients - algorithms - utilities - memory - -.. toctree:: - :caption: Experimental - :maxdepth: 3 - - python - guile - ----- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/third_party/immer/doc/introduction.rst b/third_party/immer/doc/introduction.rst deleted file mode 100644 index 2445cf9df823..000000000000 --- a/third_party/immer/doc/introduction.rst +++ /dev/null @@ -1,6 +0,0 @@ - -Introduction -============ - -.. include:: ../README.rst - :start-after: include:introduction/start diff --git a/third_party/immer/doc/memory.rst b/third_party/immer/doc/memory.rst deleted file mode 100644 index 3138b249f3f3..000000000000 --- a/third_party/immer/doc/memory.rst +++ /dev/null @@ -1,204 +0,0 @@ -Memory management -================= - -Memory management is specially important for immutable data -structures. This is mainly due to: - -#. In order to preserve the old value, new memory has to be allocated - to store the new data whenever a container is manipulated. Thus, - more allocations are performed *when changing* than with traditional - mutable data structures. - -#. In order to support *structural sharing* transparently, some kind - of garbage collection mechanism is required. Passing immutable - data structures around is, internally, just passing references, - thus the system needs to figure out somehow when old values are not - referenced anymore and should be deallocated. - -Thus, most containers in this library can be customized via policies_ -in order to use different *allocation* and *garbage collection* -strategies. - -.. doxygentypedef:: immer::default_memory_policy -.. doxygentypedef:: immer::default_heap_policy -.. doxygentypedef:: immer::default_refcount_policy - -.. _policies: https://en.wikipedia.org/wiki/Policy-based_design - -.. _memory policy: - -Memory policy -------------- - -.. doxygenstruct:: immer::memory_policy - :members: - :undoc-members: - -.. _gc: - -Example: tracing garbage collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is note worthy that all aspects of a -:cpp:class:`immer::memory_policy` are not completely orthogonal. - -Let's say you want to use a `tracing garbage collector`_. Actually, we -already provide :cpp:class:`a heap ` that interfaces -with the `Boehm's conservative garbage collector`_. Chunks of memory -allocated with this heap do not need to be deallocated, instead, after -a certain number of allocations, the heap itself will scan the stack -and all allocated memory to find references to other blocks of memory. -The memory that is not referenced anymore is automatically *freed*. -Thus, no reference counting mechanism is needed, and it makes no sense -to use this heap with anything else than the -:cpp:class:`immer::no_refcount_policy`. Also, a big object can be -separated in parts that contain pointers and parts that do not, which -make scanning references faster. So it makes most sense to use -``prefer_fewer_bigger_objects = false``. - -.. note:: There are few considerations to note when using - :cpp:class:`gc_heap` with containers. Please make sure to - read :cpp:class:`its documentation section ` - before using it. - -.. literalinclude:: ../example/vector/gc.cpp - :language: c++ - :start-after: example/start - :end-before: example/end - - -.. _boehm's conservative garbage collector: https://github.com/ivmai/bdwgc -.. _tracing garbage collector: https://en.wikipedia.org/wiki/Tracing_garbage_collection - -Heaps ------ - -A **heap policy** is a `metafunction class`_ that given the sizes of -the objects that we want to allocate, it *returns* a heap that can -allocate objects of those sizes. - -.. _metafunction class: http://www.boost.org/doc/libs/1_62_0/libs/mpl/doc/refmanual/metafunction-class.html - -A **heap** is a type with a methods ``void* allocate(std::size_t)`` -and ``void deallocate(void*)`` that return and release raw memory. -For a canonical model of this concept check the -:cpp:class:`immer::cpp_heap`. - -.. note:: Currently, *heaps* can only have **global state**. Having - internal state poses conceptual problems for immutable data - structures: should a `const` method of a container modify - its internal allocator state? Should every immutable - container object have its own internal state, or new objects - made from another one just keep a reference to the allocator - of the parent? - - On the other hand, having some **scoped state** does make - sense for some use-cases of immutable data structures. For - example, we might want to support variations of `region - based allocation`_. This interface might evolve to evolve - to support some kind of non-global state to accommodate - these use cases. - -.. _region based allocation: https://en.wikipedia.org/wiki/Region-based_memory_management - -.. admonition:: Why not use the standard allocator interface? - - The standard allocator API was not designed to support different - allocation strategies, but to abstract over the underlying memory - model instead. In C++11 the situation improves, but the new API is - *stateful*, posing various challenges as described in the previous - note. So far it was easier to provide our own allocation - interface. In the future, we will provide adaptors so - standard-compatible allocators can also be used with ``immer``. - -Heap policies -~~~~~~~~~~~~~ - -.. doxygenstruct:: immer::heap_policy - :members: - :undoc-members: - -.. doxygenstruct:: immer::free_list_heap_policy - -Standard heap -~~~~~~~~~~~~~ - -.. doxygenstruct:: immer::cpp_heap - :members: - -Malloc heap -~~~~~~~~~~~ - -.. doxygenstruct:: immer::malloc_heap - :members: - -Garbage collected heap -~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygenclass:: immer::gc_heap - -Heap adaptors -~~~~~~~~~~~~~ - -Inspired by `Andrei Alexandrescu's talk on allocators `_ and `Emery Berger's heap layers `_ we provide -allocator adaptors that can be combined using C++ mixins. These -enable building more complex allocator out of simpler strategies, or -provide application specific optimizations on top of general -allocators. - -.. _allocation vexation: https://www.youtube.com/watch?v=LIb3L4vKZ7U -.. _heap layers: https://github.com/emeryberger/Heap-Layers - -.. doxygenstruct:: immer::with_data - -.. doxygenstruct:: immer::free_list_heap - -.. doxygenstruct:: immer::thread_local_free_list_heap - -.. doxygenstruct:: immer::unsafe_free_list_heap - -.. doxygenstruct:: immer::identity_heap - -.. doxygenstruct:: immer::debug_size_heap - -.. doxygenstruct:: immer::split_heap - -.. _rc: - -Reference counting ------------------- - -`Reference counting`_ is the most commonly used garbage collection -strategy for C++. It can be implemented non-intrusively, in a way -orthogonal to the allocation strategy. It is deterministic, playing -well with RAII_. - -A `memory policy`_ can provide a reference counting strategy that -containers can use to track their contents. - -.. _reference counting: https://en.wikipedia.org/wiki/Reference_counting -.. _raii: https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization - -.. doxygenstruct:: immer::refcount_policy - -.. doxygenstruct:: immer::unsafe_refcount_policy - -.. doxygenstruct:: immer::no_refcount_policy - -Transience ----------- - -In order to support `transients`, it is needed to provide a mechanism -to track the ownership of the data allocated inside the container. -This concept is encapsulated in *transience policies*. - -Note that when :ref:`reference counting ` is available, no such mechanism is -needed. However, when :ref:`tracing garbage collection` is used instead, -a special policy has to be provided. Otherwise, the transient API is -still available, but it will perform poorly, since it won't be able to -mutate any data in place. - -.. doxygenstruct:: immer::no_transience_policy - -.. doxygenstruct:: immer::gc_transience_policy diff --git a/third_party/immer/doc/python.rst b/third_party/immer/doc/python.rst deleted file mode 120000 index 4266420dfb5b..000000000000 --- a/third_party/immer/doc/python.rst +++ /dev/null @@ -1 +0,0 @@ -../extra/python/README.rst \ No newline at end of file diff --git a/third_party/immer/doc/requirements.txt b/third_party/immer/doc/requirements.txt deleted file mode 100644 index 4d0744feec58..000000000000 --- a/third_party/immer/doc/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -git+https://github.com/arximboldi/sphinx.git -git+https://github.com/arximboldi/breathe.git -recommonmark diff --git a/third_party/immer/doc/sphinx-html-hack.bash b/third_party/immer/doc/sphinx-html-hack.bash deleted file mode 100755 index 1dccb9265dd0..000000000000 --- a/third_party/immer/doc/sphinx-html-hack.bash +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -location=`dirname $0` - -echo "Running $0 at $location" - -# Fixes issues described here among others -# https://github.com/michaeljones/breathe/issues/284 - -fix-missing-class-name() -{ - src='\(.*\)class ' - dst='\2class\1' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-missing-struct-name() -{ - src='\(.*\)struct ' - dst='\2struct\1' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-double-using-keyword() -{ - src='usingusing ' - dst='using ' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-do-not-repeat-type-in-member-using-declaration() -{ - src='using \(\([^:]*::\)*\)\([^ ]*\) = \([^<]*\)' - dst='using \3 = \4' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-do-not-repeat-type-in-member-using-declaration - -fix-remove-double-class-name() -{ - # src='\([^&]*\)<\([^&]*\)>::' - # dst='\1::' - src='\([^<]*\)' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-typedefs() -{ - src='typedef ' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-typedefs-2() -{ - src='= typedef ' - dst='= ' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-straneous-typedefs-2 - -fix-remove-straneous-using-declarations() -{ - src='using template<>
' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-template-in-using-declarations-1() -{ - src='\(
\n]*>\)\ntemplate<>
' - dst='\1' - pre=':a;N;$!ba;' - sed -i "$pre;s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-straneous-template-in-using-declarations-1 - -fix-remove-straneous-template-in-using-declarations-2() -{ - src='>template<>
`_, with some twists to turn make more idiomatic -in C++. Essentially, they are a mutable interface built on top of the -same data structures the implements the immutable containers under the -hood. - -These can be useful for :ref:`performing efficient batch -updates` or :ref:`interfacing with standard -algorithms`. - -.. _clojure-transients: https://clojure.org/reference/transients - -array_transient ---------------- - -.. doxygenclass:: immer::array_transient - :members: - :undoc-members: - -vector_transient ----------------- - -.. doxygenclass:: immer::vector_transient - :members: - :undoc-members: - -flex_vector_transient ---------------------- - -.. doxygenclass:: immer::flex_vector_transient - :members: - :undoc-members: - -set_transient -------------- - -.. doxygenclass:: immer::set_transient - :members: - :undoc-members: - -map_transient -------------- - -.. doxygenclass:: immer::map_transient - :members: - :undoc-members: diff --git a/third_party/immer/doc/utilities.rst b/third_party/immer/doc/utilities.rst deleted file mode 100644 index eaeea475c263..000000000000 --- a/third_party/immer/doc/utilities.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. highlight:: c++ - -Utilities -========= - -The library provides also some types that, while they are not exactly -immutable data-structures, they are very useful when using immutable -data-structures and value-oriented design in practice. - -atom ----- - -.. doxygenclass:: immer::atom - :members: - :undoc-members: diff --git a/third_party/immer/example/CMakeLists.txt b/third_party/immer/example/CMakeLists.txt deleted file mode 100644 index 2aa0f554279d..000000000000 --- a/third_party/immer/example/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ - -# Targets -# ======= - -add_custom_target(examples - COMMENT "Build all examples.") -add_dependencies(check examples) - -file(GLOB_RECURSE immer_examples "*.cpp") -foreach(_file IN LISTS immer_examples) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - add_dependencies(examples ${_target}) - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - target_link_libraries(${_target} PUBLIC immer-dev) - add_test("example/${_output}" ${_output}) -endforeach() diff --git a/third_party/immer/example/array/array.cpp b/third_party/immer/example/array/array.cpp deleted file mode 100644 index 43972ad61a21..000000000000 --- a/third_party/immer/example/array/array.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include - -int main() -{ - { - // include:push-back/start - auto v1 = immer::array{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::array{1})); - assert((v2 == immer::array{1, 8})); - // include:push-back/end - } - - { - // include:set/start - auto v1 = immer::array{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::array{1, 2, 3})); - assert((v2 == immer::array{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::array{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::array{1, 2, 3, 4})); - assert((v2 == immer::array{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::array{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::array{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::array{1, 2, 3})); - // include:take/end - } -} diff --git a/third_party/immer/example/box/box.cpp b/third_party/immer/example/box/box.cpp deleted file mode 100644 index 8f045e8876ec..000000000000 --- a/third_party/immer/example/box/box.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include -#include - -int main() -{ - { - // include:update/start - auto v1 = immer::box{"hello"}; - auto v2 = v1.update([&](auto l) { return l + ", world!"; }); - - assert((v1 == immer::box{"hello"})); - assert((v2 == immer::box{"hello, world!"})); - // include:update/end - } -} diff --git a/third_party/immer/example/flex-vector/flex-vector.cpp b/third_party/immer/example/flex-vector/flex-vector.cpp deleted file mode 100644 index 7c8a7793393c..000000000000 --- a/third_party/immer/example/flex-vector/flex-vector.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include - -int main() -{ - { - // include:push-back/start - auto v1 = immer::flex_vector{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::flex_vector{1})); - assert((v2 == immer::flex_vector{1, 8})); - // include:push-back/end - } - { - // include:push-front/start - auto v1 = immer::flex_vector{1}; - auto v2 = v1.push_front(8); - - assert((v1 == immer::flex_vector{1})); - assert((v2 == immer::flex_vector{8, 1})); - // include:push-front/end - } - - { - // include:set/start - auto v1 = immer::flex_vector{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::flex_vector{1, 2, 3})); - assert((v2 == immer::flex_vector{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::flex_vector{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::flex_vector{1, 2, 3, 4})); - assert((v2 == immer::flex_vector{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::flex_vector{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::flex_vector{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::flex_vector{1, 2, 3})); - // include:take/end - } - - { - // include:drop/start - auto v1 = immer::flex_vector{1, 2, 3, 4, 5, 6}; - auto v2 = v1.drop(3); - - assert((v1 == immer::flex_vector{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::flex_vector{4, 5, 6})); - // include:drop/end - } - - { - // include:insert/start - auto v1 = immer::flex_vector{1, 2, 3}; - auto v2 = v1.insert(0, 0); - - assert((v1 == immer::flex_vector{1, 2, 3})); - assert((v2 == immer::flex_vector{0, 1, 2, 3})); - // include:insert/end - } - - { - // include:erase/start - auto v1 = immer::flex_vector{1, 2, 3, 4, 5}; - auto v2 = v1.erase(2); - - assert((v1 == immer::flex_vector{1, 2, 3, 4, 5})); - assert((v2 == immer::flex_vector{1, 2, 4, 5})); - // include:erase/end - } - - { - // include:concat/start - auto v1 = immer::flex_vector{1, 2, 3}; - auto v2 = v1 + v1; - - assert((v1 == immer::flex_vector{1, 2, 3})); - assert((v2 == immer::flex_vector{1, 2, 3, 1, 2, 3})); - // include:concat/end - } -} diff --git a/third_party/immer/example/map/intro.cpp b/third_party/immer/example/map/intro.cpp deleted file mode 100644 index 94222f99b31b..000000000000 --- a/third_party/immer/example/map/intro.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -// include:intro/start -#include -int main() -{ - const auto v0 = immer::map{}; - const auto v1 = v0.set("hello", 42); - assert(v0["hello"] == 0); - assert(v1["hello"] == 42); - - const auto v2 = v1.erase("hello"); - assert(*v1.find("hello") == 42); - assert(!v2.find("hello")); -} -// include:intro/end diff --git a/third_party/immer/example/set/intro.cpp b/third_party/immer/example/set/intro.cpp deleted file mode 100644 index be932ce65475..000000000000 --- a/third_party/immer/example/set/intro.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:intro/start -#include -int main() -{ - const auto v0 = immer::set{}; - const auto v1 = v0.insert(42); - assert(v0.count(42) == 0); - assert(v1.count(42) == 1); - - const auto v2 = v1.erase(42); - assert(v1.count(42) == 1); - assert(v2.count(42) == 0); -} -// include:intro/end diff --git a/third_party/immer/example/vector/fizzbuzz.cpp b/third_party/immer/example/vector/fizzbuzz.cpp deleted file mode 100644 index c7765a6200a0..000000000000 --- a/third_party/immer/example/vector/fizzbuzz.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include - -#include -#include - -// include:fizzbuzz/start -immer::vector -fizzbuzz(immer::vector v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = std::move(v).push_back( - i % 15 == 0 ? "FizzBuzz" - : i % 5 == 0 ? "Bizz" - : i % 3 == 0 ? "Fizz" : - /* else */ std::to_string(i)); - return v; -} -// include:fizzbuzz/end - -int main() -{ - auto v = fizzbuzz({}, 0, 100); - std::copy(v.begin(), - v.end(), - std::ostream_iterator{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/gc.cpp b/third_party/immer/example/vector/gc.cpp deleted file mode 100644 index 2bc4d5116f42..000000000000 --- a/third_party/immer/example/vector/gc.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:example/start -#include -#include -#include -#include -#include - -#include - -// declare a memory policy for using a tracing garbage collector -using gc_policy = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -// alias the vector type so we are not concerned about memory policies -// in the places where we actually use it -template -using my_vector = immer::vector; - -int main() -{ - auto v = - my_vector().push_back("hello, ").push_back("world!\n"); - - for (auto s : v) - std::cout << s; -} -// include:example/end diff --git a/third_party/immer/example/vector/intro.cpp b/third_party/immer/example/vector/intro.cpp deleted file mode 100644 index ca832e606552..000000000000 --- a/third_party/immer/example/vector/intro.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:intro/start -#include -int main() -{ - const auto v0 = immer::vector{}; - const auto v1 = v0.push_back(13); - assert((v0 == immer::vector{})); - assert((v1 == immer::vector{13})); - - const auto v2 = v1.set(0, 42); - assert(v1[0] == 13); - assert(v2[0] == 42); -} -// include:intro/end diff --git a/third_party/immer/example/vector/iota-move.cpp b/third_party/immer/example/vector/iota-move.cpp deleted file mode 100644 index 3d03ba5307f5..000000000000 --- a/third_party/immer/example/vector/iota-move.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include - -// include:myiota/start -immer::vector myiota(immer::vector v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = std::move(v).push_back(i); - return v; -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-slow.cpp b/third_party/immer/example/vector/iota-slow.cpp deleted file mode 100644 index a311b7a7ff08..000000000000 --- a/third_party/immer/example/vector/iota-slow.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include - -// include:myiota/start -immer::vector myiota(immer::vector v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = v.push_back(i); - return v; -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-transient-std.cpp b/third_party/immer/example/vector/iota-transient-std.cpp deleted file mode 100644 index 451f44a10306..000000000000 --- a/third_party/immer/example/vector/iota-transient-std.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include - -#include -#include - -// include:myiota/start -immer::vector myiota(immer::vector v, int first, int last) -{ - auto t = v.transient(); - std::generate_n( - std::back_inserter(t), last - first, [&] { return first++; }); - return t.persistent(); -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-transient.cpp b/third_party/immer/example/vector/iota-transient.cpp deleted file mode 100644 index d49b14e5798d..000000000000 --- a/third_party/immer/example/vector/iota-transient.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include - -// include:myiota/start -immer::vector myiota(immer::vector v, int first, int last) -{ - auto t = v.transient(); - for (auto i = first; i < last; ++i) - t.push_back(i); - return t.persistent(); -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/move.cpp b/third_party/immer/example/vector/move.cpp deleted file mode 100644 index 7eb815b62a6e..000000000000 --- a/third_party/immer/example/vector/move.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include - -// include:move-bad/start -immer::vector do_stuff(const immer::vector v) -{ - return std::move(v).push_back(42); -} -// include:move-bad/end - -// include:move-good/start -immer::vector do_stuff_better(immer::vector v) -{ - return std::move(v).push_back(42); -} -// include:move-good/end - -int main() -{ - auto v = immer::vector{}; - auto v1 = do_stuff(v); - auto v2 = do_stuff_better(v); - assert(v1.size() == 1); - assert(v2.size() == 1); - assert(v1[0] == 42); - assert(v2[0] == 42); -} diff --git a/third_party/immer/example/vector/vector.cpp b/third_party/immer/example/vector/vector.cpp deleted file mode 100644 index c59c2d1d170b..000000000000 --- a/third_party/immer/example/vector/vector.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include - -int main() -{ - { - // include:push-back/start - auto v1 = immer::vector{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::vector{1})); - assert((v2 == immer::vector{1, 8})); - // include:push-back/end - } - - { - // include:set/start - auto v1 = immer::vector{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::vector{1, 2, 3})); - assert((v2 == immer::vector{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::vector{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::vector{1, 2, 3, 4})); - assert((v2 == immer::vector{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::vector{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::vector{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::vector{1, 2, 3})); - // include:take/end - } -} diff --git a/third_party/immer/extra/fuzzer/CMakeLists.txt b/third_party/immer/extra/fuzzer/CMakeLists.txt deleted file mode 100644 index 777289f8a12d..000000000000 --- a/third_party/immer/extra/fuzzer/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ - -add_custom_target(fuzzers - COMMENT "Build all fuzzers.") - -if (CHECK_FUZZERS) - add_dependencies(tests fuzzers) -endif() - -# LIB_FUZZING_ENGINE is set by the Google OSS-Fuzz -# infrastructure. Otherwise we use Clang's LibFuzzer -if (DEFINED ENV{LIB_FUZZING_ENGINE}) - set(immer_fuzzing_engine $ENV{LIB_FUZZING_ENGINE}) -else() - set(immer_fuzzing_engine "-fsanitize=fuzzer") -endif() - -file(GLOB_RECURSE immer_fuzzers "*.cpp") -foreach(_file IN LISTS immer_fuzzers) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - target_compile_options(${_target} PUBLIC ${immer_fuzzing_engine}) - target_link_libraries(${_target} PUBLIC ${immer_fuzzing_engine} - immer-dev) - add_dependencies(fuzzers ${_target}) - if (CHECK_FUZZERS) - add_test("fuzzer/${_output}" ${_output} -max_total_time=1) - endif() -endforeach() diff --git a/third_party/immer/extra/fuzzer/array-gc.cpp b/third_party/immer/extra/fuzzer/array-gc.cpp deleted file mode 100644 index b93721225288..000000000000 --- a/third_party/immer/extra/fuzzer/array-gc.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include -#include -#include - -#include - -using gc_memory = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using array_t = immer::array; - using transient_t = typename array_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array{}; - auto ts = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_push_back_mut, - op_update_mut, - op_take_mut, - }; - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_transient: { - auto src = read(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/array.cpp b/third_party/immer/extra/fuzzer/array.cpp deleted file mode 100644 index 094d97b7f425..000000000000 --- a/third_party/immer/extra/fuzzer/array.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include - -#include - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using array_t = immer::array; - using size_t = std::uint8_t; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_push_back_move, - op_update_move, - op_take_move, - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(12); - break; - } - case op_update_move: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/flex-vector-gc.cpp b/third_party/immer/extra/fuzzer/flex-vector-gc.cpp deleted file mode 100644 index 00c302898675..000000000000 --- a/third_party/immer/extra/fuzzer/flex-vector-gc.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include -#include -#include - -#include - -using gc_memory = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = immer::flex_vector; - using transient_t = typename vector_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array{}; - auto ts = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < var_count && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - auto max = std::numeric_limits::max() >> (bits * 4); - return v1.size() < max && v2.size() < max; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_mut, - op_update_mut, - op_take_mut, - op_drop_mut, - op_prepend_mut, - op_prepend_mut_move, - op_append_mut, - op_append_mut_move, - }; - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_transient: { - auto src = read(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_drop: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_size(vs[src])); - vs[dst] = vs[src].drop(idx); - break; - } - case op_concat: { - auto src = read(in, is_valid_var); - auto src2 = read(in, is_valid_var); - if (can_concat(vs[src], vs[src2])) - vs[dst] = vs[src] + vs[src2]; - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - case op_prepend_mut: { - auto src = read(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) - ts[dst].prepend(ts[src]); - break; - } - case op_prepend_mut_move: { - auto src = read(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - ts[dst].prepend(std::move(ts[src])); - ts[src] = {}; - } - break; - } - case op_append_mut: { - auto src = read(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) - ts[dst].append(ts[src]); - break; - } - case op_append_mut_move: { - auto src = read(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - ts[dst].append(std::move(ts[src])); - ts[src] = {}; - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/flex-vector.cpp b/third_party/immer/extra/fuzzer/flex-vector.cpp deleted file mode 100644 index 14395de1d5ae..000000000000 --- a/third_party/immer/extra/fuzzer/flex-vector.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include - -#include - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 8; - constexpr auto bits = 2; - - using vector_t = - immer::flex_vector; - using size_t = std::uint8_t; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < var_count && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - auto max = std::numeric_limits::max() >> (bits * 4); - return v1.size() < max && v2.size() < max; - }; - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_move, - op_update_move, - op_take_move, - op_drop_move, - op_concat_move_l, - op_concat_move_r, - op_concat_move_lr, - op_insert, - op_erase, - op_compare, - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read(in, is_valid_var); - if (can_concat(vars[src], vars[src2])) - vars[dst] = vars[src] + vars[src2]; - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(21); - break; - } - case op_update_move: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - case op_drop_move: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).drop(idx); - break; - } - case op_concat_move_l: { - auto src2 = read(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = std::move(vars[src]) + vars[src2]; - break; - } - case op_concat_move_r: { - auto src2 = read(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = vars[src] + std::move(vars[src2]); - break; - } - case op_concat_move_lr: { - auto src2 = read(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = std::move(vars[src]) + std::move(vars[src2]); - } - case op_compare: { - using std::swap; - if (vars[src] == vars[dst]) - swap(vars[src], vars[dst]); - break; - } - case op_erase: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = vars[src].erase(idx); - break; - } - case op_insert: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = vars[src].insert(idx, immer::box{42}); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/fuzzer_input.hpp b/third_party/immer/extra/fuzzer/fuzzer_input.hpp deleted file mode 100644 index 485b7dc72b44..000000000000 --- a/third_party/immer/extra/fuzzer/fuzzer_input.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include - -struct no_more_input : std::exception -{}; - -struct fuzzer_input -{ - const std::uint8_t* data_; - std::size_t size_; - - const std::uint8_t* next(std::size_t size) - { - if (size_ < size) - throw no_more_input{}; - auto r = data_; - data_ += size; - size_ -= size; - return r; - } - - const std::uint8_t* next(std::size_t size, std::size_t align) - { - auto rem = size % align; - if (rem) - next(align - rem); - return next(size); - } - - template - int run(Fn step) - { - try { - while (step(*this)) - continue; - } catch (const no_more_input&) {}; - return 0; - } -}; - -template -const T& read(fuzzer_input& fz) -{ - return *reinterpret_cast(fz.next(sizeof(T), alignof(T))); -} - -template -T read(fuzzer_input& fz, Cond cond) -{ - auto x = read(fz); - return cond(x) ? x : read(fz, cond); -} diff --git a/third_party/immer/extra/fuzzer/map-gc.cpp b/third_party/immer/extra/fuzzer/map-gc.cpp deleted file mode 100644 index 835f37a05897..000000000000 --- a/third_party/immer/extra/fuzzer/map-gc.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include -#include - -#include - -using gc_memory = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using map_t = - immer::map, std::equal_to, gc_memory>; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_set, - op_erase, - op_set_move, - op_erase_move, - op_iterate, - op_find, - op_update - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_set: { - auto value = read(in); - vars[dst] = vars[src].set(value, 42); - break; - } - case op_erase: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_set_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).set(value, 42); - break; - } - case op_erase_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].set(v.first, v.second); - } - break; - } - case op_find: { - auto value = read(in); - auto res = vars[src].find(value); - if (res != nullptr) { - vars[dst] = vars[dst].set(*res, 42); - } - break; - } - case op_update: { - auto key = read(in); - vars[dst] = vars[src].update(key, [](int x) { return x + 1; }); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/map.cpp b/third_party/immer/extra/fuzzer/map.cpp deleted file mode 100644 index eb650679e932..000000000000 --- a/third_party/immer/extra/fuzzer/map.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include - -#include - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using map_t = immer::map; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_set, - op_erase, - op_set_move, - op_erase_move, - op_iterate, - op_find, - op_update - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_set: { - auto value = read(in); - vars[dst] = vars[src].set(value, 42); - break; - } - case op_erase: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_set_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).set(value, 42); - break; - } - case op_erase_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].set(v.first, v.second); - } - break; - } - case op_find: { - auto value = read(in); - auto res = vars[src].find(value); - if (res != nullptr) { - vars[dst] = vars[dst].set(*res, 42); - } - break; - } - case op_update: { - auto key = read(in); - vars[dst] = vars[src].update(key, [](int x) { return x + 1; }); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/set-gc.cpp b/third_party/immer/extra/fuzzer/set-gc.cpp deleted file mode 100644 index 3b88c08f3c2d..000000000000 --- a/third_party/immer/extra/fuzzer/set-gc.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include -#include - -#include - -using gc_memory = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using set_t = - immer::set, std::equal_to, gc_memory>; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_insert, - op_erase, - op_insert_move, - op_erase_move, - op_iterate - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_insert: { - auto value = read(in); - vars[dst] = vars[src].insert(value); - break; - } - case op_erase: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_insert_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).insert(value); - break; - } - case op_erase_move: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].insert(v); - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/set.cpp b/third_party/immer/extra/fuzzer/set.cpp deleted file mode 100644 index b25313d18cfc..000000000000 --- a/third_party/immer/extra/fuzzer/set.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include - -#include - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using set_t = immer::set; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_insert, - op_erase, - op_insert_move, - op_erase_move, - op_iterate - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_insert: { - auto value = read(in); - vars[dst] = vars[src].insert(value); - break; - } - case op_erase: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_insert_move: { - auto value = read(in); - vars[dst] = std::move(vars[src]).insert(value); - break; - } - case op_erase_move: { - auto value = read(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].insert(v); - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/vector-gc.cpp b/third_party/immer/extra/fuzzer/vector-gc.cpp deleted file mode 100644 index 1faa729c5a72..000000000000 --- a/third_party/immer/extra/fuzzer/vector-gc.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include -#include -#include -#include - -#include - -using gc_memory = immer::memory_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = immer::vector; - using transient_t = typename vector_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array{}; - auto ts = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_push_back_mut, - op_update_mut, - op_take_mut, - }; - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_transient: { - auto src = read(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read(in, is_valid_var); - auto idx = read(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/vector.cpp b/third_party/immer/extra/fuzzer/vector.cpp deleted file mode 100644 index b04cbcee870c..000000000000 --- a/third_party/immer/extra/fuzzer/vector.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include - -#include - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = - immer::vector; - using size_t = std::uint8_t; - - auto vars = std::array{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_push_back_move, - op_update_move, - op_take_move, - }; - auto src = read(in, is_valid_var); - auto dst = read(in, is_valid_var); - switch (read(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(12); - break; - } - case op_update_move: { - auto idx = read(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/guile/CMakeLists.txt b/third_party/immer/extra/guile/CMakeLists.txt deleted file mode 100644 index 99338060d6da..000000000000 --- a/third_party/immer/extra/guile/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ - -find_package(PkgConfig) - -pkg_check_modules(Guile guile-2.2) - -if (NOT Guile_FOUND) - message(STATUS "Disabling Guile modules") - return() -endif() - -set(GUILE_EXTENSION_DIR ${CMAKE_CURRENT_BINARY_DIR}) -configure_file(immer.scm.in immer.scm) - -add_library(guile-immer SHARED EXCLUDE_FROM_ALL - src/immer.cpp) -target_include_directories(guile-immer PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} - ${CALLABLE_TRAITS_INCLUDE_DIR} - ${Guile_INCLUDE_DIRS}) -target_link_libraries(guile-immer PUBLIC - immer - ${Guile_LIBRARIES}) - -add_custom_target(guile DEPENDS guile-immer) diff --git a/third_party/immer/extra/guile/README.rst b/third_party/immer/extra/guile/README.rst deleted file mode 100644 index 09cf8be644ec..000000000000 --- a/third_party/immer/extra/guile/README.rst +++ /dev/null @@ -1,144 +0,0 @@ - -Guile bindings -============== - -This library includes experimental bindings bring efficient immutable -vectors for the `GNU Guile`_ Scheme implementation. The interface is -somewhat **incomplete**, but you can already do something interesting -things like: - -.. literalinclude:: ../extra/guile/example.scm - :language: scheme - :start-after: intro/start - :end-before: intro/end -.. - - **Do you want to help** making these bindings complete and production - ready? Drop a line at `immer@sinusoid.al - `_ or `open an issue on Github - `_ - -.. _GNU Guile: https://www.gnu.org/software/guile/ - -Installation ------------- - -.. highlight:: sh - -To install the software, you need `GNU Guile 2.2 -`_. Then you have to -`clone the repository `_ and -inside the repository do something like:: - - mkdir build; cd build - cmake .. -DCMAKE_BUILD_TYPE=Release \ - -DGUILE_EXTENSION_DIR="" - make guile - cp extra/guile/libguile-immer.so "<...the GUILE_EXTENSION_DIR>" - cp extra/guile/immer.scm "" - -Benchmarks ----------- - -The library includes some quick and dirty benchmarks that show how -these vectors perform compared to *mutable vectors*, *lists*, and -*v-lists*. Once you have installed the library, you may run them by -executing the following in the project root:: - - guile extra/guile/benchmark.scm - -This is the output I get when running those: - -.. code-block:: scheme - :name: benchmark-output - - (define bench-size 1000000) - (define bench-samples 10) - ;;;; benchmarking creation... - ; evaluating: - (apply ivector (iota bench-size)) - ; average time: 0.0608697784 seconds - ; evaluating: - (apply ivector-u32 (iota bench-size)) - ; average time: 0.0567354933 seconds - ; evaluating: - (iota bench-size) - ; average time: 0.032995402 seconds - ; evaluating: - (apply vector (iota bench-size)) - ; average time: 0.0513594425 seconds - ; evaluating: - (apply u32vector (iota bench-size)) - ; average time: 0.0939185315 seconds - ; evaluating: - (list->vlist (iota bench-size)) - ; average time: 0.2369570977 seconds - ;;;; benchmarking iteration... - (define bench-ivector (apply ivector (iota bench-size))) - (define bench-ivector-u32 (apply ivector-u32 (iota bench-size))) - (define bench-list (iota bench-size)) - (define bench-vector (apply vector (iota bench-size))) - (define bench-u32vector (apply u32vector (iota bench-size))) - (define bench-vlist (list->vlist (iota bench-size))) - ; evaluating: - (ivector-fold + 0 bench-ivector) - ; average time: 0.035750341 seconds - ; evaluating: - (ivector-u32-fold + 0 bench-ivector-u32) - ; average time: 0.0363843682 seconds - ; evaluating: - (fold + 0 bench-list) - ; average time: 0.0271881423 seconds - ; evaluating: - (vector-fold + 0 bench-vector) - ; average time: 0.0405022349 seconds - ; evaluating: - (vlist-fold + 0 bench-vlist) - ; average time: 0.0424709098 seconds - ;;;; benchmarking iteration by index... - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (ivector-length bench-ivector)) - (iter (+ i 1) (+ acc (ivector-ref bench-ivector i))) - acc)) - ; average time: 0.2195658936 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (ivector-u32-length bench-ivector-u32)) - (iter (+ i 1) (+ acc (ivector-u32-ref bench-ivector-u32 i))) - acc)) - ; average time: 0.2205486326 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (vector-length bench-vector)) - (iter (+ i 1) (+ acc (vector-ref bench-vector i))) - acc)) - ; average time: 0.0097157637 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (u32vector-length bench-u32vector)) - (iter (+ i 1) (+ acc (u32vector-ref bench-u32vector i))) - acc)) - ; average time: 0.0733736008 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (vlist-length bench-vlist)) - (iter (+ i 1) (+ acc (vlist-ref bench-vlist i))) - acc)) - ; average time: 0.3220357243 seconds - ;;;; benchmarking concatenation... - ; evaluating: - (ivector-append bench-ivector bench-ivector) - ; average time: 1.63022e-5 seconds - ; evaluating: - (ivector-u32-append bench-ivector-u32 bench-ivector-u32) - ; average time: 1.63754e-5 seconds - ; evaluating: - (append bench-list bench-list) - ; average time: 0.0135592963 seconds - ; evaluating: - (vector-append bench-vector bench-vector) - ; average time: 0.0044506586 seconds - ; evaluating: - (vlist-append bench-vlist bench-vlist) - ; average time: 0.3227312512 seconds diff --git a/third_party/immer/extra/guile/benchmark.scm b/third_party/immer/extra/guile/benchmark.scm deleted file mode 100644 index 463a8eb17d9e..000000000000 --- a/third_party/immer/extra/guile/benchmark.scm +++ /dev/null @@ -1,168 +0,0 @@ -;; -;; immer: immutable data structures for C++ -;; Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -;; -;; This software is distributed under the Boost Software License, Version 1.0. -;; See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -;; - -(use-modules (immer) - (fector) ; https://wingolog.org/pub/fector.scm - (srfi srfi-1) - (srfi srfi-43) - (ice-9 vlist) - (ice-9 pretty-print) - (rnrs bytevectors)) - -(define-syntax display-eval - (syntax-rules () - ((_ expr) - (begin (pretty-print 'expr - #:max-expr-width 72) - expr)))) - -(display-eval (define bench-size 1000000)) -(display-eval (define bench-samples 10)) - -(define (average . ns) - (/ (apply + ns) (length ns))) - -(define (generate-n n fn) - (unfold (lambda (x) (= x n)) - (lambda (x) (fn)) - (lambda (x) (+ x 1)) - 0)) - -(define-syntax benchmark - (syntax-rules () - ((_ expr) - (begin - (display "; evaluating: ") (newline) - (pretty-print 'expr - #:max-expr-width 72 - #:per-line-prefix " ") - (let* ((sample (lambda () - (gc) - (let* ((t0 (get-internal-real-time)) - (r expr) - (t1 (get-internal-real-time))) - (/ (- t1 t0) internal-time-units-per-second)))) - (samples (generate-n bench-samples sample)) - (result (apply average samples))) - (display "; average time: ") - (display (exact->inexact result)) - (display " seconds") - (newline)))))) - -(display ";;;; benchmarking creation...") (newline) - -(display-eval - (define (fector . args) - (persistent-fector (fold (lambda (v fv) (fector-push! fv v)) - (transient-fector) - args)))) - -(benchmark (apply ivector (iota bench-size))) -(benchmark (apply ivector-u32 (iota bench-size))) -(benchmark (iota bench-size)) -(benchmark (apply vector (iota bench-size))) -(benchmark (apply u32vector (iota bench-size))) -(benchmark (list->vlist (iota bench-size))) -(benchmark (apply fector (iota bench-size))) - -(display ";;;; benchmarking iteration...") (newline) - -(display-eval (define bench-ivector (apply ivector (iota bench-size)))) -(display-eval (define bench-ivector-u32 (apply ivector-u32 (iota bench-size)))) -(display-eval (define bench-list (iota bench-size))) -(display-eval (define bench-vector (apply vector (iota bench-size)))) -(display-eval (define bench-u32vector (apply u32vector (iota bench-size)))) -(display-eval (define bench-vlist (list->vlist (iota bench-size)))) -(display-eval (define bench-fector (apply fector (iota bench-size)))) -(display-eval (define bench-bytevector-u32 - (uint-list->bytevector (iota bench-size) - (native-endianness) - 4))) - -(benchmark (ivector-fold + 0 bench-ivector)) -(benchmark (ivector-u32-fold + 0 bench-ivector-u32)) -(benchmark (fold + 0 bench-list)) -(benchmark (vector-fold + 0 bench-vector)) -(benchmark (vlist-fold + 0 bench-vlist)) -(benchmark (fector-fold + bench-fector 0)) - -(display ";;;; benchmarking iteration by index...") (newline) - -(display-eval - (define-syntax iteration-by-index - (syntax-rules () - ((_ *length *ref *vector *step) - (let ((len (*length *vector))) - (let iter ((i 0) (acc 0)) - (if (< i len) - (iter (+ i *step) - (+ acc (*ref *vector i))) - acc))))))) - -(display-eval - (define-syntax iteration-by-index-truncate - (syntax-rules () - ((_ *length *ref *vector *step) - (let ((len (*length *vector))) - (let iter ((i 0) (acc 0)) - (if (< i len) - (iter (+ i *step) - (logand #xffffffffFFFFFFFF - (+ acc (*ref *vector i)))) - acc))))))) - -(benchmark (iteration-by-index ivector-length - ivector-ref - bench-ivector 1)) -(benchmark (iteration-by-index ivector-u32-length - ivector-u32-ref - bench-ivector-u32 1)) -(benchmark (iteration-by-index vector-length - vector-ref - bench-vector 1)) -(benchmark (iteration-by-index u32vector-length - u32vector-ref - bench-u32vector 1)) -(benchmark (iteration-by-index vlist-length - vlist-ref - bench-vlist 1)) -(benchmark (iteration-by-index fector-length - fector-ref - bench-fector 1)) -(benchmark (iteration-by-index bytevector-length - bytevector-u32-native-ref - bench-bytevector-u32 4)) - -(benchmark (iteration-by-index-truncate ivector-length - ivector-ref - bench-ivector 1)) -(benchmark (iteration-by-index-truncate ivector-u32-length - ivector-u32-ref - bench-ivector-u32 1)) -(benchmark (iteration-by-index-truncate vector-length - vector-ref - bench-vector 1)) -(benchmark (iteration-by-index-truncate u32vector-length - u32vector-ref - bench-u32vector 1)) -(benchmark (iteration-by-index-truncate vlist-length - vlist-ref - bench-vlist 1)) -(benchmark (iteration-by-index-truncate fector-length - fector-ref - bench-fector 1)) -(benchmark (iteration-by-index-truncate bytevector-length - bytevector-u32-native-ref - bench-bytevector-u32 4)) - -(display ";;;; benchmarking concatenation...") (newline) -(benchmark (ivector-append bench-ivector bench-ivector)) -(benchmark (ivector-u32-append bench-ivector-u32 bench-ivector-u32)) -(benchmark (append bench-list bench-list)) -(benchmark (vector-append bench-vector bench-vector)) -(benchmark (vlist-append bench-vlist bench-vlist)) diff --git a/third_party/immer/extra/guile/example.scm b/third_party/immer/extra/guile/example.scm deleted file mode 100644 index 6649508cedc3..000000000000 --- a/third_party/immer/extra/guile/example.scm +++ /dev/null @@ -1,51 +0,0 @@ -;; -;; immer: immutable data structures for C++ -;; Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -;; -;; This software is distributed under the Boost Software License, Version 1.0. -;; See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -;; - -;; include:intro/start -(use-modules (immer) - (rnrs base)) - -(let ((v1 (ivector 1 "hola" 3 'que #:tal))) - (assert (eq? (ivector-ref v1 3) 'que)) - - (let* ((v2 (ivector-set v1 3 'what)) - (v2 (ivector-update v2 2 (lambda (x) (+ 1 x))))) - (assert (eq? (ivector-ref v1 2) 3)) - (assert (eq? (ivector-ref v1 3) 'que)) - (assert (eq? (ivector-ref v2 2) 4)) - (assert (eq? (ivector-ref v2 3) 'what)) - - (let ((v3 (ivector-push v2 "hehe"))) - (assert (eq? (ivector-length v3) 6)) - (assert (eq? (ivector-ref v3 (- (ivector-length v3) 1)) "hehe"))))) - -(let ((v (apply ivector (iota 10)))) - (assert (eq? (ivector-length v) 10)) - (assert (eq? (ivector-length (ivector-drop v 3)) 7)) - (assert (eq? (ivector-length (ivector-take v 3)) 3)) - (assert (eq? (ivector-length (ivector-append v v)) 20))) - -(let ((v1 (make-ivector 3)) - (v2 (make-ivector 3 ":)"))) - (assert (eq? (ivector-ref v1 2) - (vector-ref (make-vector 3) 2))) - (assert (eq? (ivector-ref v2 2) ":)"))) -;; include:intro/end - -;; Experiments - -(let ((d (dummy))) - (dummy-foo d) - (dummy-bar d 42)) -(gc) - -(func1) -(func2) -(func3 (dummy) 12) -(foo-func1) -(gc) diff --git a/third_party/immer/extra/guile/immer.scm.in b/third_party/immer/extra/guile/immer.scm.in deleted file mode 100644 index 8624aabd5bf4..000000000000 --- a/third_party/immer/extra/guile/immer.scm.in +++ /dev/null @@ -1,5 +0,0 @@ -(define-module (immer)) - -;; The extension automatically exports the names via 'scm_c_export' -(load-extension "@GUILE_EXTENSION_DIR@/libguile-immer" - "init_immer") diff --git a/third_party/immer/extra/guile/scm/detail/convert.hpp b/third_party/immer/extra/guile/scm/detail/convert.hpp deleted file mode 100644 index 4c87ff185669..000000000000 --- a/third_party/immer/extra/guile/scm/detail/convert.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include - -#include -#include -#include - -#include - -namespace scm { -namespace detail { - -template -struct convert; - -template -auto to_scm(T&& v) - -> SCM_DECLTYPE_RETURN( - convert>::to_scm(std::forward(v))); - -template -auto to_cpp(SCM v) - -> SCM_DECLTYPE_RETURN( - convert>::to_cpp(v)); - -} // namespace detail -} // namespace scm - -#define SCM_DECLARE_NUMERIC_TYPE(cpp_name__, scm_name__) \ - namespace scm { \ - namespace detail { \ - template <> \ - struct convert { \ - static cpp_name__ to_cpp(SCM v) { return scm_to_ ## scm_name__(v); } \ - static SCM to_scm(cpp_name__ v) { return scm_from_ ## scm_name__(v); } \ - }; \ - }} /* namespace scm::detail */ \ - /**/ - -SCM_DECLARE_NUMERIC_TYPE(float, double); -SCM_DECLARE_NUMERIC_TYPE(double, double); -SCM_DECLARE_NUMERIC_TYPE(std::int8_t, int8); -SCM_DECLARE_NUMERIC_TYPE(std::int16_t, int16); -SCM_DECLARE_NUMERIC_TYPE(std::int32_t, int32); -SCM_DECLARE_NUMERIC_TYPE(std::int64_t, int64); -SCM_DECLARE_NUMERIC_TYPE(std::uint8_t, uint8); -SCM_DECLARE_NUMERIC_TYPE(std::uint16_t, uint16); -SCM_DECLARE_NUMERIC_TYPE(std::uint32_t, uint32); -SCM_DECLARE_NUMERIC_TYPE(std::uint64_t, uint64); diff --git a/third_party/immer/extra/guile/scm/detail/define.hpp b/third_party/immer/extra/guile/scm/detail/define.hpp deleted file mode 100644 index 08b6e763381f..000000000000 --- a/third_party/immer/extra/guile/scm/detail/define.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#ifndef SCM_AUTO_EXPORT -#define SCM_AUTO_EXPORT 1 -#endif - -#include -#include - -namespace scm { -namespace detail { - -template -static void define_impl(const std::string& name, Fn fn) -{ - using args_t = function_args_t; - constexpr auto args_size = pack_size_v; - constexpr auto has_rest = std::is_same, scm::args>{}; - constexpr auto arg_count = args_size - has_rest; - auto subr = (scm_t_subr) +subr_wrapper_aux(fn, args_t{}); - scm_c_define_gsubr(name.c_str(), arg_count, 0, has_rest, subr); -#if SCM_AUTO_EXPORT - scm_c_export(name.c_str()); -#endif -} - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp b/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp deleted file mode 100644 index 258249eb2c73..000000000000 --- a/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include -#include - -namespace scm { -namespace detail { -// this anonymous namespace should help avoiding registration clashes -// among translation units. -namespace { - -template -auto finalizer_wrapper_impl(Fn fn, pack<>) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] { invoke(fn_); }; -} -template -auto finalizer_wrapper_impl(Fn fn, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1) { invoke(fn_, to_cpp(a1)); }; -} -template -auto finalizer_wrapper_impl(Fn fn, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) { - invoke(fn_, to_cpp(a1), to_cpp(a2)); - }; -} -template -auto finalizer_wrapper_impl(Fn fn, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) { - invoke(fn_, to_cpp(a1), to_cpp(a2), to_cpp(a3)); - }; -} - -template -auto finalizer_wrapper(Fn fn) -{ - return finalizer_wrapper_impl(fn, function_args_t{}); -} - -} // anonymous namespace -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/function_args.hpp b/third_party/immer/extra/guile/scm/detail/function_args.hpp deleted file mode 100644 index 809e3eb1979b..000000000000 --- a/third_party/immer/extra/guile/scm/detail/function_args.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include - -namespace scm { -namespace detail { - -template -using function_args_t = boost::callable_traits::args_t; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/invoke.hpp b/third_party/immer/extra/guile/scm/detail/invoke.hpp deleted file mode 100644 index d9f2b37ccece..000000000000 --- a/third_party/immer/extra/guile/scm/detail/invoke.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -// Adapted from the official std::invoke proposal: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html - -#include -#include - -namespace scm { -namespace detail { - -template -std::enable_if_t< - std::is_member_pointer>::value, - std::result_of_t> -invoke(Functor&& f, Args&&... args) -{ - return std::mem_fn(f)(std::forward(args)...); -} - -template -std::enable_if_t< - !std::is_member_pointer>::value, - std::result_of_t> -invoke(Functor&& f, Args&&... args) -{ - return std::forward(f)(std::forward(args)...); -} - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/pack.hpp b/third_party/immer/extra/guile/scm/detail/pack.hpp deleted file mode 100644 index 9a1813570bcd..000000000000 --- a/third_party/immer/extra/guile/scm/detail/pack.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -namespace scm { -namespace detail { - -struct none_t; - -template -struct pack {}; - -template -struct pack_size; - -template -struct pack_size> -{ - static constexpr auto value = sizeof...(Ts); -}; - -template -constexpr auto pack_size_v = pack_size::value; - -template -struct pack_last -{ - using type = none_t; -}; - -template -struct pack_last> - : pack_last> -{}; - -template -struct pack_last> -{ - using type = T; -}; - -template -using pack_last_t = typename pack_last::type; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp b/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp deleted file mode 100644 index fc11ff1c51ec..000000000000 --- a/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include -#include - -namespace scm { -namespace detail { - -// this anonymous namespace should help avoiding registration clashes -// among translation units. -namespace { - -template -auto subr_wrapper_impl(Fn fn, pack, pack<>) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] () -> SCM { return to_scm(invoke(fn_)); }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1) -> SCM { - return to_scm(invoke(fn_, to_cpp(a1))); - }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) -> SCM { - return to_scm(invoke(fn_, to_cpp(a1), to_cpp(a2))); - }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) -> SCM { - return to_scm(invoke(fn_, to_cpp(a1), to_cpp(a2), - to_cpp(a3))); - }; -} - -template -auto subr_wrapper_impl(Fn fn, pack, pack<>) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] () -> SCM { invoke(fn_); return SCM_UNSPECIFIED; }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1) -> SCM { - invoke(fn_, to_cpp(a1)); return SCM_UNSPECIFIED; - }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) -> SCM { - invoke(fn_, to_cpp(a1), to_cpp(a2)); - return SCM_UNSPECIFIED; - }; -} -template -auto subr_wrapper_impl(Fn fn, pack, pack) -{ - check_call_once(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) -> SCM { - invoke(fn_, to_cpp(a1), to_cpp(a2), to_cpp(a3)); - return SCM_UNSPECIFIED; - }; -} - -template -auto subr_wrapper_aux(Fn fn, pack) -{ - return subr_wrapper_impl( - fn, pack>{}, pack{}); -} - -template -auto subr_wrapper(Fn fn) -{ - return subr_wrapper_aux(fn, function_args_t{}); -} - -} // anonymous namespace -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/util.hpp b/third_party/immer/extra/guile/scm/detail/util.hpp deleted file mode 100644 index fdc323722e99..000000000000 --- a/third_party/immer/extra/guile/scm/detail/util.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include - -namespace scm { -namespace detail { - -#define SCM_DECLTYPE_RETURN(...) \ - decltype(__VA_ARGS__) \ - { return __VA_ARGS__; } \ - /**/ - -template -constexpr bool is_valid_v = true; - -template -using is_valid_t = void; - -template -void check_call_once() -{ - static bool called = false; - if (called) scm_misc_error (nullptr, "Double defined binding. \ -This may be caused because there are multiple C++ binding groups in the same \ -translation unit. You may solve this by using different type tags for each \ -binding group.", SCM_EOL); - called = true; -} - -struct move_sequence -{ - move_sequence() = default; - move_sequence(const move_sequence&) = delete; - move_sequence(move_sequence&& other) - { other.moved_from_ = true; }; - - bool moved_from_ = false; -}; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/group.hpp b/third_party/immer/extra/guile/scm/group.hpp deleted file mode 100644 index 69cd385820cb..000000000000 --- a/third_party/immer/extra/guile/scm/group.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include - -namespace scm { -namespace detail { - -template -struct definer -{ - using this_t = definer; - using next_t = definer; - - std::string group_name_ = {}; - - definer() = default; - definer(definer&&) = default; - - template > - definer(definer) - {} - - template - next_t define(std::string name, Fn fn) && - { - define_impl(name, fn); - return { std::move(*this) }; - } - - template - next_t maker(Fn fn) && - { - define_impl("make", fn); - return { std::move(*this) }; - } -}; - -template -struct group_definer -{ - using this_t = group_definer; - using next_t = group_definer; - - std::string group_name_ = {}; - - group_definer(std::string name) - : group_name_{std::move(name)} {} - - group_definer(group_definer&&) = default; - - template > - group_definer(group_definer) - {} - - template - next_t define(std::string name, Fn fn) && - { - define_impl(group_name_ + "-" + name, fn); - return { std::move(*this) }; - } -}; - -} // namespace detail - -template -detail::definer group() -{ - return {}; -} - -template -detail::group_definer group(std::string name) -{ - return { std::move(name) }; -} - -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/list.hpp b/third_party/immer/extra/guile/scm/list.hpp deleted file mode 100644 index dc162c200244..000000000000 --- a/third_party/immer/extra/guile/scm/list.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include - -namespace scm { - -struct list : detail::wrapper -{ - using base_t = detail::wrapper; - using base_t::base_t; - - using iterator = list; - using value_type = val; - - list() : base_t{SCM_EOL} {}; - list end() const { return {}; } - list begin() const { return *this; } - - explicit operator bool() { return handle_ != SCM_EOL; } - - val operator* () const { return val{scm_car(handle_)}; } - - list& operator++ () - { - handle_ = scm_cdr(handle_); - return *this; - } - - list operator++ (int) - { - auto result = *this; - result.handle_ = scm_cdr(handle_); - return result; - } -}; - -struct args : list -{ - using list::list; -}; - -} // namespace scm - -SCM_DECLARE_WRAPPER_TYPE(scm::list); -SCM_DECLARE_WRAPPER_TYPE(scm::args); diff --git a/third_party/immer/extra/guile/scm/scm.hpp b/third_party/immer/extra/guile/scm/scm.hpp deleted file mode 100644 index f4e4989a44a9..000000000000 --- a/third_party/immer/extra/guile/scm/scm.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include -#include -#include diff --git a/third_party/immer/extra/guile/scm/type.hpp b/third_party/immer/extra/guile/scm/type.hpp deleted file mode 100644 index da53ed46ef8b..000000000000 --- a/third_party/immer/extra/guile/scm/type.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include -#include -#include - -namespace scm { -namespace detail { - -template -struct foreign_type_storage -{ - static SCM data; -}; - -template -SCM foreign_type_storage::data = SCM_UNSPECIFIED; - -template -struct convert_foreign_type -{ - using storage_t = foreign_type_storage; - static T& to_cpp(SCM v) - { - assert(storage_t::data != SCM_UNSPECIFIED && - "can not convert to undefined type"); - scm_assert_foreign_object_type(storage_t::data, v); - return *(T*)scm_foreign_object_ref(v, 0); - } - - template - static SCM to_scm(U&& v) - { - assert(storage_t::data != SCM_UNSPECIFIED && - "can not convert from undefined type"); - return scm_make_foreign_object_1( - storage_t::data, - new (scm_gc_malloc(sizeof(T), "scmpp")) T( - std::forward(v))); - } -}; - -// Assume that every other type is foreign -template -struct convert::value && - // only value types are supported at - // the moment but the story might - // change later... - !std::is_pointer::value>> - : convert_foreign_type -{ -}; - -template -struct type_definer : move_sequence -{ - using this_t = type_definer; - using next_t = type_definer; - - std::string type_name_ = {}; - scm_t_struct_finalize finalizer_ = nullptr; - - type_definer(type_definer&&) = default; - - type_definer(std::string type_name) - : type_name_(std::move(type_name)) - {} - - ~type_definer() - { - if (!moved_from_) { - using storage_t = detail::foreign_type_storage; - assert(storage_t::data == SCM_UNSPECIFIED); - storage_t::data = scm_make_foreign_object_type( - scm_from_utf8_symbol(("<" + type_name_ + ">").c_str()), - scm_list_1(scm_from_utf8_symbol("data")), - finalizer_); - } - } - - template > - type_definer(type_definer r) - : move_sequence{std::move(r)} - , type_name_{std::move(r.type_name_)} - , finalizer_{std::move(r.finalizer_)} - {} - - next_t constructor() && - { - define_impl(type_name_, [] { return T{}; }); - return { std::move(*this) }; - } - - template - next_t constructor(Fn fn) && - { - define_impl(type_name_, fn); - return { std::move(*this) }; - } - - next_t finalizer() && - { - finalizer_ = (scm_t_struct_finalize) +finalizer_wrapper( - [] (T& x) { x.~T(); }); - return { std::move(*this) }; - } - - template - next_t finalizer(Fn fn) && - { - finalizer_ = (scm_t_struct_finalize) +finalizer_wrapper(fn); - return { std::move(*this) }; - } - - next_t maker() && - { - define_impl("make-" + type_name_, [] { return T{}; }); - return { std::move(*this) }; - } - - template - next_t maker(Fn fn) && - { - define_impl("make-" + type_name_, fn); - return { std::move(*this) }; - } - - template - next_t define(std::string name, Fn fn) && - { - define_impl(type_name_ + "-" + name, fn); - return { std::move(*this) }; - } -}; - -} // namespace detail - -template -detail::type_definer type(std::string type_name) -{ - return { type_name }; -} - -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/val.hpp b/third_party/immer/extra/guile/scm/val.hpp deleted file mode 100644 index 63d7189262da..000000000000 --- a/third_party/immer/extra/guile/scm/val.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include - -namespace scm { -namespace detail { - -template -struct convert_wrapper_type -{ - static T to_cpp(SCM v) { return T{v}; } - static SCM to_scm(T v) { return v.get(); } -}; - -struct wrapper -{ - wrapper() = default; - wrapper(SCM hdl) : handle_{hdl} {} - SCM get() const { return handle_; } - operator SCM () const { return handle_; } - - bool operator==(wrapper other) { return handle_ == other.handle_; } - bool operator!=(wrapper other) { return handle_ != other.handle_; } - -protected: - SCM handle_ = SCM_UNSPECIFIED; -}; - -} // namespace detail - -struct val : detail::wrapper -{ - using base_t = detail::wrapper; - using base_t::base_t; - - template , val>{} && - !std::is_same, SCM>{})>> - val(T&& x) - : base_t(detail::to_scm(std::forward(x))) - {} - - template (SCM{}))>{}>> - operator T() const { return detail::to_cpp(handle_); } - - template (SCM{}))>{}>> - operator T& () const { return detail::to_cpp(handle_); } - - template (SCM{}))>{}>> - operator const T& () const { return detail::to_cpp(handle_); } - - val operator() () const - { return val{scm_call_0(get())}; } - val operator() (val a0) const - { return val{scm_call_1(get(), a0)}; } - val operator() (val a0, val a1) const - { return val{scm_call_2(get(), a0, a1)}; } - val operator() (val a0, val a1, val a3) const - { return val{scm_call_3(get(), a0, a1, a3)}; } -}; - -} // namespace scm - -#define SCM_DECLARE_WRAPPER_TYPE(cpp_name__) \ - namespace scm { \ - namespace detail { \ - template <> \ - struct convert \ - : convert_wrapper_type {}; \ - }} /* namespace scm::detail */ \ - /**/ - -SCM_DECLARE_WRAPPER_TYPE(val); diff --git a/third_party/immer/extra/guile/src/immer.cpp b/third_party/immer/extra/guile/src/immer.cpp deleted file mode 100644 index 7933447a8d18..000000000000 --- a/third_party/immer/extra/guile/src/immer.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include -#include -#include - -namespace { - -struct guile_heap -{ - static void* allocate(std::size_t size) - { return scm_gc_malloc(size, "immer"); } - - static void* allocate(std::size_t size, immer::norefs_tag) - { return scm_gc_malloc_pointerless(size, "immer"); } - - template - static void deallocate(std::size_t size, void* obj, Tags...) - { scm_gc_free(obj, size, "immer"); } -}; - -using guile_memory = immer::memory_policy< - immer::heap_policy, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template -using guile_ivector = immer::flex_vector; - -struct dummy -{ - SCM port_ = scm_current_warning_port(); - - dummy(dummy&&) - { scm_puts("~~ dummy move constructor\n", port_); } - - dummy() - { scm_puts("~~ dummy default constructor\n", port_); } - - ~dummy() - { scm_puts("~~ dummy finalized\n", port_); } - - void foo() - { scm_puts("~~ dummy foo\n", port_); } - - int bar(int x) - { - auto res = x + 42; - scm_puts("~~ dummy bar: ", port_); - scm_display(scm::val{res}, port_); - scm_newline(port_); - return res; - } -}; - -template -void func() -{ - auto port = scm_current_warning_port(); - scm_puts("~~ func", port); - scm_display(scm_from_int(I), port); - scm_newline(port); -} - -template -void init_ivector(std::string type_name = "") -{ - using namespace std::string_literals; - - using self_t = guile_ivector; - using size_t = typename self_t::size_type; - - auto name = "ivector"s + (type_name.empty() ? ""s : "-" + type_name); - - scm::type(name) - .constructor([] (scm::args rest) { - return self_t(rest.begin(), rest.end()); - }) - .maker([] (size_t n, scm::args rest) { - return self_t(n, rest ? *rest : scm::val{}); - }) - .define("ref", &self_t::operator[]) - .define("length", &self_t::size) - .define("set", [] (const self_t& v, size_t i, scm::val x) { - return v.set(i, x); - }) - .define("update", [] (const self_t& v, size_t i, scm::val fn) { - return v.update(i, fn); - }) - .define("push", [] (const self_t& v, scm::val x) { - return v.push_back(x); - }) - .define("take", [] (const self_t& v, size_t s) { - return v.take(s); - }) - .define("drop", [] (const self_t& v, size_t s) { - return v.drop(s); - }) - .define("append", [] (self_t v, scm::args rest) { - for (auto x : rest) - v = v + x; - return v; - }) - .define("fold", [] (scm::val fn, scm::val first, const self_t& v) { - return immer::accumulate(v, first, fn); - }) - ; -} - -} // anonymous namespace - -struct bar_tag_t {}; - -extern "C" -void init_immer() -{ - scm::type("dummy") - .constructor() - .finalizer() - .define("foo", &dummy::foo) - .define("bar", &dummy::bar); - - scm::group() - .define("func1", func<1>); - - scm::group() - .define("func2", func<2>) - .define("func3", &dummy::bar); - - scm::group("foo") - .define("func1", func<1>); - - init_ivector(); - init_ivector("u8"); - init_ivector("u16"); - init_ivector("u32"); - init_ivector("u64"); - init_ivector("s8"); - init_ivector("s16"); - init_ivector("s32"); - init_ivector("s64"); - init_ivector("f32"); - init_ivector("f64"); -} diff --git a/third_party/immer/extra/js/immer.cpp b/third_party/immer/extra/js/immer.cpp deleted file mode 100644 index d0d77c8a2c55..000000000000 --- a/third_party/immer/extra/js/immer.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include -#include -#include - -namespace { - -using memory_t = immer::memory_policy< - immer::unsafe_free_list_heap_policy, - immer::unsafe_refcount_policy>; - -template -using js_vector_t = immer::vector; - -template -VectorT range(typename VectorT::value_type first, - typename VectorT::value_type last) -{ - auto v = VectorT{}; - for (; first != last; ++first) - v = std::move(v).push_back(first); - return v; -} - -template -VectorT range_slow(typename VectorT::value_type first, - typename VectorT::value_type last) -{ - auto v = VectorT{}; - for (; first != last; ++first) - v = v.push_back(first); - return v; -} - -template -VectorT push_back(VectorT& v, typename VectorT::value_type x) -{ return v.push_back(x); } - -template -VectorT set(VectorT& v, std::size_t i, typename VectorT::value_type x) -{ return v.set(i, x); } - -template -void bind_vector(const char* name) -{ - using emscripten::class_; - - using vector_t = js_vector_t; - - class_(name) - .constructor() - .function("push", &push_back) - .function("set", &set) - .function("get", &vector_t::operator[]) - .property("size", &vector_t::size); -} - -} // anonymous namespace - -EMSCRIPTEN_BINDINGS(immer) -{ - using emscripten::function; - - bind_vector("Vector"); - bind_vector("VectorInt"); - bind_vector("VectorNumber"); - - function("range_int", &range>); - function("rangeSlow_int", &range_slow>); - function("range_double", &range>); - function("rangeSlow_double", &range_slow>); -} diff --git a/third_party/immer/extra/js/index.js b/third_party/immer/extra/js/index.js deleted file mode 100644 index 6da994164f8e..000000000000 --- a/third_party/immer/extra/js/index.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * immer: immutable data structures for C++ - * Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente - * - * This software is distributed under the Boost Software License, Version 1.0. - * See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - */ - -var immer = Module - -var N = 1000 - -var suite = new Benchmark.Suite('push') - .add('Immutable.List', function(){ - var v = new Immutable.List - for (var x = 0; x < N; ++x) - v = v.push(x) - }) - .add('mori.vector', function(){ - var v = mori.vector() - for (var x = 0; x < N; ++x) - v = mori.conj.f2(v, x) - }) - .add('mori.vector-Transient', function(){ - var v = mori.mutable.thaw(mori.vector()) - for (var x = 0; x < N; ++x) - v = mori.mutable.conj.f2(v, x) - return mori.mutable.freeze(v) - }) - .add('immer.Vector', function(){ - var v = new immer.Vector - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - }) - .add('immer.VectorInt', function(){ - var v = new immer.VectorInt - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - v.delete() - }) - .add('immer.VectorNumber', function(){ - var v = new immer.VectorNumber - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - v.delete() - }) - .add('immer.VectorInt-Native', function(){ - immer.rangeSlow_int(0, N).delete() - }) - .add('immer.VectorInt-NativeTransient', function(){ - immer.range_int(0, N).delete() - }) - .add('immer.VectorDouble-Native', function(){ - immer.rangeSlow_double(0, N).delete() - }) - .add('immer.VectorDouble-NativeTransient', function(){ - immer.range_double(0, N).delete() - }) - .on('cycle', function(event) { - console.log(String(event.target)); - }) - .on('complete', function() { - console.log('Fastest is ' + this.filter('fastest').map('name')); - }) - .run({ 'async': true }) diff --git a/third_party/immer/extra/js/index.tpl.html b/third_party/immer/extra/js/index.tpl.html deleted file mode 100644 index fdbd40a86a10..000000000000 --- a/third_party/immer/extra/js/index.tpl.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/third_party/immer/extra/js/lib/benchmark.js b/third_party/immer/extra/js/lib/benchmark.js deleted file mode 100644 index 11bc2babaf25..000000000000 --- a/third_party/immer/extra/js/lib/benchmark.js +++ /dev/null @@ -1,2811 +0,0 @@ -/*! - * Benchmark.js - * Copyright 2010-2016 Mathias Bynens - * Based on JSLitmus.js, copyright Robert Kieffer - * Modified by John-David Dalton - * Available under MIT license - */ -;(function() { - 'use strict'; - - /** Used as a safe reference for `undefined` in pre ES5 environments. */ - var undefined; - - /** Used to determine if values are of the language type Object. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `define`. */ - var freeDefine = typeof define == 'function' && typeof define.amd == 'object' && define.amd && define; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** Detect free variable `require`. */ - var freeRequire = typeof require == 'function' && require; - - /** Used to assign each benchmark an incremented id. */ - var counter = 0; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Used to detect primitive types. */ - var rePrimitive = /^(?:boolean|number|string|undefined)$/; - - /** Used to make every compiled test unique. */ - var uidCounter = 0; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Date', 'Function', 'Math', 'Object', 'RegExp', 'String', '_', - 'clearTimeout', 'chrome', 'chromium', 'document', 'navigator', 'phantom', - 'platform', 'process', 'runtime', 'setTimeout' - ]; - - /** Used to avoid hz of Infinity. */ - var divisors = { - '1': 4096, - '2': 512, - '3': 64, - '4': 8, - '5': 0 - }; - - /** - * T-Distribution two-tailed critical values for 95% confidence. - * For more info see http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm. - */ - var tTable = { - '1': 12.706, '2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447, - '7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179, - '13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101, - '19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064, - '25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042, - 'infinity': 1.96 - }; - - /** - * Critical Mann-Whitney U-values for 95% confidence. - * For more info see http://www.saburchill.com/IBbiology/stats/003.html. - */ - var uTable = { - '5': [0, 1, 2], - '6': [1, 2, 3, 5], - '7': [1, 3, 5, 6, 8], - '8': [2, 4, 6, 8, 10, 13], - '9': [2, 4, 7, 10, 12, 15, 17], - '10': [3, 5, 8, 11, 14, 17, 20, 23], - '11': [3, 6, 9, 13, 16, 19, 23, 26, 30], - '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37], - '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45], - '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55], - '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64], - '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75], - '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87], - '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99], - '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113], - '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127], - '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142], - '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158], - '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175], - '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192], - '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211], - '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230], - '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250], - '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272], - '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294], - '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317] - }; - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `Benchmark` function using the given `context` object. - * - * @static - * @memberOf Benchmark - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `Benchmark` function. - */ - function runInContext(context) { - // Exit early if unable to acquire lodash. - var _ = context && context._ || require('lodash') || root._; - if (!_) { - Benchmark.runInContext = runInContext; - return Benchmark; - } - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, - Function = context.Function, - Math = context.Math, - Object = context.Object, - RegExp = context.RegExp, - String = context.String; - - /** Used for `Array` and `Object` method references. */ - var arrayRef = [], - objectProto = Object.prototype; - - /** Native method shortcuts. */ - var abs = Math.abs, - clearTimeout = context.clearTimeout, - floor = Math.floor, - log = Math.log, - max = Math.max, - min = Math.min, - pow = Math.pow, - push = arrayRef.push, - setTimeout = context.setTimeout, - shift = arrayRef.shift, - slice = arrayRef.slice, - sqrt = Math.sqrt, - toString = objectProto.toString, - unshift = arrayRef.unshift; - - /** Used to avoid inclusion in Browserified bundles. */ - var req = require; - - /** Detect DOM document object. */ - var doc = isHostType(context, 'document') && context.document; - - /** Used to access Wade Simmons' Node.js `microtime` module. */ - var microtimeObject = req('microtime'); - - /** Used to access Node.js's high resolution timer. */ - var processObject = isHostType(context, 'process') && context.process; - - /** Used to prevent a `removeChild` memory leak in IE < 9. */ - var trash = doc && doc.createElement('div'); - - /** Used to integrity check compiled tests. */ - var uid = 'uid' + _.now(); - - /** Used to avoid infinite recursion when methods call each other. */ - var calledBy = {}; - - /** - * An object used to flag environments/features. - * - * @static - * @memberOf Benchmark - * @type Object - */ - var support = {}; - - (function() { - - /** - * Detect if running in a browser environment. - * - * @memberOf Benchmark.support - * @type boolean - */ - support.browser = doc && isHostType(context, 'navigator') && !isHostType(context, 'phantom'); - - /** - * Detect if the Timers API exists. - * - * @memberOf Benchmark.support - * @type boolean - */ - support.timeout = isHostType(context, 'setTimeout') && isHostType(context, 'clearTimeout'); - - /** - * Detect if function decompilation is support. - * - * @name decompilation - * @memberOf Benchmark.support - * @type boolean - */ - try { - // Safari 2.x removes commas in object literals from `Function#toString` results. - // See http://webk.it/11609 for more details. - // Firefox 3.6 and Opera 9.25 strip grouping parentheses from `Function#toString` results. - // See http://bugzil.la/559438 for more details. - support.decompilation = Function( - ('return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')') - // Avoid issues with code added by Istanbul. - .replace(/__cov__[^;]+;/g, '') - )()(0).x === '1'; - } catch(e) { - support.decompilation = false; - } - }()); - - /** - * Timer object used by `clock()` and `Deferred#resolve`. - * - * @private - * @type Object - */ - var timer = { - - /** - * The timer namespace object or constructor. - * - * @private - * @memberOf timer - * @type {Function|Object} - */ - 'ns': Date, - - /** - * Starts the deferred timer. - * - * @private - * @memberOf timer - * @param {Object} deferred The deferred instance. - */ - 'start': null, // Lazy defined in `clock()`. - - /** - * Stops the deferred timer. - * - * @private - * @memberOf timer - * @param {Object} deferred The deferred instance. - */ - 'stop': null // Lazy defined in `clock()`. - }; - - /*------------------------------------------------------------------------*/ - - /** - * The Benchmark constructor. - * - * Note: The Benchmark constructor exposes a handful of lodash methods to - * make working with arrays, collections, and objects easier. The lodash - * methods are: - * [`each/forEach`](https://lodash.com/docs#forEach), [`forOwn`](https://lodash.com/docs#forOwn), - * [`has`](https://lodash.com/docs#has), [`indexOf`](https://lodash.com/docs#indexOf), - * [`map`](https://lodash.com/docs#map), and [`reduce`](https://lodash.com/docs#reduce) - * - * @constructor - * @param {string} name A name to identify the benchmark. - * @param {Function|string} fn The test to benchmark. - * @param {Object} [options={}] Options object. - * @example - * - * // basic usage (the `new` operator is optional) - * var bench = new Benchmark(fn); - * - * // or using a name first - * var bench = new Benchmark('foo', fn); - * - * // or with options - * var bench = new Benchmark('foo', fn, { - * - * // displayed by `Benchmark#toString` if `name` is not available - * 'id': 'xyz', - * - * // called when the benchmark starts running - * 'onStart': onStart, - * - * // called after each run cycle - * 'onCycle': onCycle, - * - * // called when aborted - * 'onAbort': onAbort, - * - * // called when a test errors - * 'onError': onError, - * - * // called when reset - * 'onReset': onReset, - * - * // called when the benchmark completes running - * 'onComplete': onComplete, - * - * // compiled/called before the test loop - * 'setup': setup, - * - * // compiled/called after the test loop - * 'teardown': teardown - * }); - * - * // or name and options - * var bench = new Benchmark('foo', { - * - * // a flag to indicate the benchmark is deferred - * 'defer': true, - * - * // benchmark test function - * 'fn': function(deferred) { - * // call `Deferred#resolve` when the deferred test is finished - * deferred.resolve(); - * } - * }); - * - * // or options only - * var bench = new Benchmark({ - * - * // benchmark name - * 'name': 'foo', - * - * // benchmark test as a string - * 'fn': '[1,2,3,4].sort()' - * }); - * - * // a test's `this` binding is set to the benchmark instance - * var bench = new Benchmark('foo', function() { - * 'My name is '.concat(this.name); // "My name is foo" - * }); - */ - function Benchmark(name, fn, options) { - var bench = this; - - // Allow instance creation without the `new` operator. - if (!(bench instanceof Benchmark)) { - return new Benchmark(name, fn, options); - } - // Juggle arguments. - if (_.isPlainObject(name)) { - // 1 argument (options). - options = name; - } - else if (_.isFunction(name)) { - // 2 arguments (fn, options). - options = fn; - fn = name; - } - else if (_.isPlainObject(fn)) { - // 2 arguments (name, options). - options = fn; - fn = null; - bench.name = name; - } - else { - // 3 arguments (name, fn [, options]). - bench.name = name; - } - setOptions(bench, options); - - bench.id || (bench.id = ++counter); - bench.fn == null && (bench.fn = fn); - - bench.stats = cloneDeep(bench.stats); - bench.times = cloneDeep(bench.times); - } - - /** - * The Deferred constructor. - * - * @constructor - * @memberOf Benchmark - * @param {Object} clone The cloned benchmark instance. - */ - function Deferred(clone) { - var deferred = this; - if (!(deferred instanceof Deferred)) { - return new Deferred(clone); - } - deferred.benchmark = clone; - clock(deferred); - } - - /** - * The Event constructor. - * - * @constructor - * @memberOf Benchmark - * @param {Object|string} type The event type. - */ - function Event(type) { - var event = this; - if (type instanceof Event) { - return type; - } - return (event instanceof Event) - ? _.assign(event, { 'timeStamp': _.now() }, typeof type == 'string' ? { 'type': type } : type) - : new Event(type); - } - - /** - * The Suite constructor. - * - * Note: Each Suite instance has a handful of wrapped lodash methods to - * make working with Suites easier. The wrapped lodash methods are: - * [`each/forEach`](https://lodash.com/docs#forEach), [`indexOf`](https://lodash.com/docs#indexOf), - * [`map`](https://lodash.com/docs#map), and [`reduce`](https://lodash.com/docs#reduce) - * - * @constructor - * @memberOf Benchmark - * @param {string} name A name to identify the suite. - * @param {Object} [options={}] Options object. - * @example - * - * // basic usage (the `new` operator is optional) - * var suite = new Benchmark.Suite; - * - * // or using a name first - * var suite = new Benchmark.Suite('foo'); - * - * // or with options - * var suite = new Benchmark.Suite('foo', { - * - * // called when the suite starts running - * 'onStart': onStart, - * - * // called between running benchmarks - * 'onCycle': onCycle, - * - * // called when aborted - * 'onAbort': onAbort, - * - * // called when a test errors - * 'onError': onError, - * - * // called when reset - * 'onReset': onReset, - * - * // called when the suite completes running - * 'onComplete': onComplete - * }); - */ - function Suite(name, options) { - var suite = this; - - // Allow instance creation without the `new` operator. - if (!(suite instanceof Suite)) { - return new Suite(name, options); - } - // Juggle arguments. - if (_.isPlainObject(name)) { - // 1 argument (options). - options = name; - } else { - // 2 arguments (name [, options]). - suite.name = name; - } - setOptions(suite, options); - } - - /*------------------------------------------------------------------------*/ - - /** - * A specialized version of `_.cloneDeep` which only clones arrays and plain - * objects assigning all other values by reference. - * - * @private - * @param {*} value The value to clone. - * @returns {*} The cloned value. - */ - var cloneDeep = _.partial(_.cloneDeepWith, _, function(value) { - // Only clone primitives, arrays, and plain objects. - return (_.isObject(value) && !_.isArray(value) && !_.isPlainObject(value)) - ? value - : undefined; - }); - - /** - * Creates a function from the given arguments string and body. - * - * @private - * @param {string} args The comma separated function arguments. - * @param {string} body The function body. - * @returns {Function} The new function. - */ - function createFunction() { - // Lazy define. - createFunction = function(args, body) { - var result, - anchor = freeDefine ? freeDefine.amd : Benchmark, - prop = uid + 'createFunction'; - - runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}'); - result = anchor[prop]; - delete anchor[prop]; - return result; - }; - // Fix JaegerMonkey bug. - // For more information see http://bugzil.la/639720. - createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || _.noop)() == uid ? createFunction : Function; - return createFunction.apply(null, arguments); - } - - /** - * Delay the execution of a function based on the benchmark's `delay` property. - * - * @private - * @param {Object} bench The benchmark instance. - * @param {Object} fn The function to execute. - */ - function delay(bench, fn) { - bench._timerId = _.delay(fn, bench.delay * 1e3); - } - - /** - * Destroys the given element. - * - * @private - * @param {Element} element The element to destroy. - */ - function destroyElement(element) { - trash.appendChild(element); - trash.innerHTML = ''; - } - - /** - * Gets the name of the first argument from a function's source. - * - * @private - * @param {Function} fn The function. - * @returns {string} The argument name. - */ - function getFirstArgument(fn) { - return (!_.has(fn, 'toString') && - (/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || ''; - } - - /** - * Computes the arithmetic mean of a sample. - * - * @private - * @param {Array} sample The sample. - * @returns {number} The mean. - */ - function getMean(sample) { - return (_.reduce(sample, function(sum, x) { - return sum + x; - }) / sample.length) || 0; - } - - /** - * Gets the source code of a function. - * - * @private - * @param {Function} fn The function. - * @returns {string} The function's source code. - */ - function getSource(fn) { - var result = ''; - if (isStringable(fn)) { - result = String(fn); - } else if (support.decompilation) { - // Escape the `{` for Firefox 1. - result = _.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn), 1); - } - // Trim string. - result = (result || '').replace(/^\s+|\s+$/g, ''); - - // Detect strings containing only the "use strict" directive. - return /^(?:\/\*+[\w\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result) - ? '' - : result; - } - - /** - * Checks if an object is of the specified class. - * - * @private - * @param {*} value The value to check. - * @param {string} name The name of the class. - * @returns {boolean} Returns `true` if the value is of the specified class, else `false`. - */ - function isClassOf(value, name) { - return value != null && toString.call(value) == '[object ' + name + ']'; - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - if (object == null) { - return false; - } - var type = typeof object[property]; - return !rePrimitive.test(type) && (type != 'object' || !!object[property]); - } - - /** - * Checks if a value can be safely coerced to a string. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the value can be coerced, else `false`. - */ - function isStringable(value) { - return _.isString(value) || (_.has(value, 'toString') && _.isFunction(value.toString)); - } - - /** - * A wrapper around `require` to suppress `module missing` errors. - * - * @private - * @param {string} id The module id. - * @returns {*} The exported module or `null`. - */ - function require(id) { - try { - var result = freeExports && freeRequire(id); - } catch(e) {} - return result || null; - } - - /** - * Runs a snippet of JavaScript via script injection. - * - * @private - * @param {string} code The code to run. - */ - function runScript(code) { - var anchor = freeDefine ? define.amd : Benchmark, - script = doc.createElement('script'), - sibling = doc.getElementsByTagName('script')[0], - parent = sibling.parentNode, - prop = uid + 'runScript', - prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();'; - - // Firefox 2.0.0.2 cannot use script injection as intended because it executes - // asynchronously, but that's OK because script injection is only used to avoid - // the previously commented JaegerMonkey bug. - try { - // Remove the inserted script *before* running the code to avoid differences - // in the expected script element count/order of the document. - script.appendChild(doc.createTextNode(prefix + code)); - anchor[prop] = function() { destroyElement(script); }; - } catch(e) { - parent = parent.cloneNode(false); - sibling = null; - script.text = code; - } - parent.insertBefore(script, sibling); - delete anchor[prop]; - } - - /** - * A helper function for setting options/event handlers. - * - * @private - * @param {Object} object The benchmark or suite instance. - * @param {Object} [options={}] Options object. - */ - function setOptions(object, options) { - options = object.options = _.assign({}, cloneDeep(object.constructor.options), cloneDeep(options)); - - _.forOwn(options, function(value, key) { - if (value != null) { - // Add event listeners. - if (/^on[A-Z]/.test(key)) { - _.each(key.split(' '), function(key) { - object.on(key.slice(2).toLowerCase(), value); - }); - } else if (!_.has(object, key)) { - object[key] = cloneDeep(value); - } - } - }); - } - - /*------------------------------------------------------------------------*/ - - /** - * Handles cycling/completing the deferred benchmark. - * - * @memberOf Benchmark.Deferred - */ - function resolve() { - var deferred = this, - clone = deferred.benchmark, - bench = clone._original; - - if (bench.aborted) { - // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete. - deferred.teardown(); - clone.running = false; - cycle(deferred); - } - else if (++deferred.cycles < clone.count) { - clone.compiled.call(deferred, context, timer); - } - else { - timer.stop(deferred); - deferred.teardown(); - delay(clone, function() { cycle(deferred); }); - } - } - - /*------------------------------------------------------------------------*/ - - /** - * A generic `Array#filter` like method. - * - * @static - * @memberOf Benchmark - * @param {Array} array The array to iterate over. - * @param {Function|string} callback The function/alias called per iteration. - * @returns {Array} A new array of values that passed callback filter. - * @example - * - * // get odd numbers - * Benchmark.filter([1, 2, 3, 4, 5], function(n) { - * return n % 2; - * }); // -> [1, 3, 5]; - * - * // get fastest benchmarks - * Benchmark.filter(benches, 'fastest'); - * - * // get slowest benchmarks - * Benchmark.filter(benches, 'slowest'); - * - * // get benchmarks that completed without erroring - * Benchmark.filter(benches, 'successful'); - */ - function filter(array, callback) { - if (callback === 'successful') { - // Callback to exclude those that are errored, unrun, or have hz of Infinity. - callback = function(bench) { - return bench.cycles && _.isFinite(bench.hz) && !bench.error; - }; - } - else if (callback === 'fastest' || callback === 'slowest') { - // Get successful, sort by period + margin of error, and filter fastest/slowest. - var result = filter(array, 'successful').sort(function(a, b) { - a = a.stats; b = b.stats; - return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback === 'fastest' ? 1 : -1); - }); - - return _.filter(result, function(bench) { - return result[0].compare(bench) == 0; - }); - } - return _.filter(array, callback); - } - - /** - * Converts a number to a more readable comma-separated string representation. - * - * @static - * @memberOf Benchmark - * @param {number} number The number to convert. - * @returns {string} The more readable string representation. - */ - function formatNumber(number) { - number = String(number).split('.'); - return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') + - (number[1] ? '.' + number[1] : ''); - } - - /** - * Invokes a method on all items in an array. - * - * @static - * @memberOf Benchmark - * @param {Array} benches Array of benchmarks to iterate over. - * @param {Object|string} name The name of the method to invoke OR options object. - * @param {...*} [args] Arguments to invoke the method with. - * @returns {Array} A new array of values returned from each method invoked. - * @example - * - * // invoke `reset` on all benchmarks - * Benchmark.invoke(benches, 'reset'); - * - * // invoke `emit` with arguments - * Benchmark.invoke(benches, 'emit', 'complete', listener); - * - * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks - * Benchmark.invoke(benches, { - * - * // invoke the `run` method - * 'name': 'run', - * - * // pass a single argument - * 'args': true, - * - * // treat as queue, removing benchmarks from front of `benches` until empty - * 'queued': true, - * - * // called before any benchmarks have been invoked. - * 'onStart': onStart, - * - * // called between invoking benchmarks - * 'onCycle': onCycle, - * - * // called after all benchmarks have been invoked. - * 'onComplete': onComplete - * }); - */ - function invoke(benches, name) { - var args, - bench, - queued, - index = -1, - eventProps = { 'currentTarget': benches }, - options = { 'onStart': _.noop, 'onCycle': _.noop, 'onComplete': _.noop }, - result = _.toArray(benches); - - /** - * Invokes the method of the current object and if synchronous, fetches the next. - */ - function execute() { - var listeners, - async = isAsync(bench); - - if (async) { - // Use `getNext` as the first listener. - bench.on('complete', getNext); - listeners = bench.events.complete; - listeners.splice(0, 0, listeners.pop()); - } - // Execute method. - result[index] = _.isFunction(bench && bench[name]) ? bench[name].apply(bench, args) : undefined; - // If synchronous return `true` until finished. - return !async && getNext(); - } - - /** - * Fetches the next bench or executes `onComplete` callback. - */ - function getNext(event) { - var cycleEvent, - last = bench, - async = isAsync(last); - - if (async) { - last.off('complete', getNext); - last.emit('complete'); - } - // Emit "cycle" event. - eventProps.type = 'cycle'; - eventProps.target = last; - cycleEvent = Event(eventProps); - options.onCycle.call(benches, cycleEvent); - - // Choose next benchmark if not exiting early. - if (!cycleEvent.aborted && raiseIndex() !== false) { - bench = queued ? benches[0] : result[index]; - if (isAsync(bench)) { - delay(bench, execute); - } - else if (async) { - // Resume execution if previously asynchronous but now synchronous. - while (execute()) {} - } - else { - // Continue synchronous execution. - return true; - } - } else { - // Emit "complete" event. - eventProps.type = 'complete'; - options.onComplete.call(benches, Event(eventProps)); - } - // When used as a listener `event.aborted = true` will cancel the rest of - // the "complete" listeners because they were already called above and when - // used as part of `getNext` the `return false` will exit the execution while-loop. - if (event) { - event.aborted = true; - } else { - return false; - } - } - - /** - * Checks if invoking `Benchmark#run` with asynchronous cycles. - */ - function isAsync(object) { - // Avoid using `instanceof` here because of IE memory leak issues with host objects. - var async = args[0] && args[0].async; - return name == 'run' && (object instanceof Benchmark) && - ((async == null ? object.options.async : async) && support.timeout || object.defer); - } - - /** - * Raises `index` to the next defined index or returns `false`. - */ - function raiseIndex() { - index++; - - // If queued remove the previous bench. - if (queued && index > 0) { - shift.call(benches); - } - // If we reached the last index then return `false`. - return (queued ? benches.length : index < result.length) - ? index - : (index = false); - } - // Juggle arguments. - if (_.isString(name)) { - // 2 arguments (array, name). - args = slice.call(arguments, 2); - } else { - // 2 arguments (array, options). - options = _.assign(options, name); - name = options.name; - args = _.isArray(args = 'args' in options ? options.args : []) ? args : [args]; - queued = options.queued; - } - // Start iterating over the array. - if (raiseIndex() !== false) { - // Emit "start" event. - bench = result[index]; - eventProps.type = 'start'; - eventProps.target = bench; - options.onStart.call(benches, Event(eventProps)); - - // End early if the suite was aborted in an "onStart" listener. - if (name == 'run' && (benches instanceof Suite) && benches.aborted) { - // Emit "cycle" event. - eventProps.type = 'cycle'; - options.onCycle.call(benches, Event(eventProps)); - // Emit "complete" event. - eventProps.type = 'complete'; - options.onComplete.call(benches, Event(eventProps)); - } - // Start method execution. - else { - if (isAsync(bench)) { - delay(bench, execute); - } else { - while (execute()) {} - } - } - } - return result; - } - - /** - * Creates a string of joined array values or object key-value pairs. - * - * @static - * @memberOf Benchmark - * @param {Array|Object} object The object to operate on. - * @param {string} [separator1=','] The separator used between key-value pairs. - * @param {string} [separator2=': '] The separator used between keys and values. - * @returns {string} The joined result. - */ - function join(object, separator1, separator2) { - var result = [], - length = (object = Object(object)).length, - arrayLike = length === length >>> 0; - - separator2 || (separator2 = ': '); - _.each(object, function(value, key) { - result.push(arrayLike ? value : key + separator2 + value); - }); - return result.join(separator1 || ','); - } - - /*------------------------------------------------------------------------*/ - - /** - * Aborts all benchmarks in the suite. - * - * @name abort - * @memberOf Benchmark.Suite - * @returns {Object} The suite instance. - */ - function abortSuite() { - var event, - suite = this, - resetting = calledBy.resetSuite; - - if (suite.running) { - event = Event('abort'); - suite.emit(event); - if (!event.cancelled || resetting) { - // Avoid infinite recursion. - calledBy.abortSuite = true; - suite.reset(); - delete calledBy.abortSuite; - - if (!resetting) { - suite.aborted = true; - invoke(suite, 'abort'); - } - } - } - return suite; - } - - /** - * Adds a test to the benchmark suite. - * - * @memberOf Benchmark.Suite - * @param {string} name A name to identify the benchmark. - * @param {Function|string} fn The test to benchmark. - * @param {Object} [options={}] Options object. - * @returns {Object} The suite instance. - * @example - * - * // basic usage - * suite.add(fn); - * - * // or using a name first - * suite.add('foo', fn); - * - * // or with options - * suite.add('foo', fn, { - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - * - * // or name and options - * suite.add('foo', { - * 'fn': fn, - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - * - * // or options only - * suite.add({ - * 'name': 'foo', - * 'fn': fn, - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - */ - function add(name, fn, options) { - var suite = this, - bench = new Benchmark(name, fn, options), - event = Event({ 'type': 'add', 'target': bench }); - - if (suite.emit(event), !event.cancelled) { - suite.push(bench); - } - return suite; - } - - /** - * Creates a new suite with cloned benchmarks. - * - * @name clone - * @memberOf Benchmark.Suite - * @param {Object} options Options object to overwrite cloned options. - * @returns {Object} The new suite instance. - */ - function cloneSuite(options) { - var suite = this, - result = new suite.constructor(_.assign({}, suite.options, options)); - - // Copy own properties. - _.forOwn(suite, function(value, key) { - if (!_.has(result, key)) { - result[key] = value && _.isFunction(value.clone) - ? value.clone() - : cloneDeep(value); - } - }); - return result; - } - - /** - * An `Array#filter` like method. - * - * @name filter - * @memberOf Benchmark.Suite - * @param {Function|string} callback The function/alias called per iteration. - * @returns {Object} A new suite of benchmarks that passed callback filter. - */ - function filterSuite(callback) { - var suite = this, - result = new suite.constructor(suite.options); - - result.push.apply(result, filter(suite, callback)); - return result; - } - - /** - * Resets all benchmarks in the suite. - * - * @name reset - * @memberOf Benchmark.Suite - * @returns {Object} The suite instance. - */ - function resetSuite() { - var event, - suite = this, - aborting = calledBy.abortSuite; - - if (suite.running && !aborting) { - // No worries, `resetSuite()` is called within `abortSuite()`. - calledBy.resetSuite = true; - suite.abort(); - delete calledBy.resetSuite; - } - // Reset if the state has changed. - else if ((suite.aborted || suite.running) && - (suite.emit(event = Event('reset')), !event.cancelled)) { - suite.aborted = suite.running = false; - if (!aborting) { - invoke(suite, 'reset'); - } - } - return suite; - } - - /** - * Runs the suite. - * - * @name run - * @memberOf Benchmark.Suite - * @param {Object} [options={}] Options object. - * @returns {Object} The suite instance. - * @example - * - * // basic usage - * suite.run(); - * - * // or with options - * suite.run({ 'async': true, 'queued': true }); - */ - function runSuite(options) { - var suite = this; - - suite.reset(); - suite.running = true; - options || (options = {}); - - invoke(suite, { - 'name': 'run', - 'args': options, - 'queued': options.queued, - 'onStart': function(event) { - suite.emit(event); - }, - 'onCycle': function(event) { - var bench = event.target; - if (bench.error) { - suite.emit({ 'type': 'error', 'target': bench }); - } - suite.emit(event); - event.aborted = suite.aborted; - }, - 'onComplete': function(event) { - suite.running = false; - suite.emit(event); - } - }); - return suite; - } - - /*------------------------------------------------------------------------*/ - - /** - * Executes all registered listeners of the specified event type. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {Object|string} type The event type or object. - * @param {...*} [args] Arguments to invoke the listener with. - * @returns {*} Returns the return value of the last listener executed. - */ - function emit(type) { - var listeners, - object = this, - event = Event(type), - events = object.events, - args = (arguments[0] = event, arguments); - - event.currentTarget || (event.currentTarget = object); - event.target || (event.target = object); - delete event.result; - - if (events && (listeners = _.has(events, event.type) && events[event.type])) { - _.each(listeners.slice(), function(listener) { - if ((event.result = listener.apply(object, args)) === false) { - event.cancelled = true; - } - return !event.aborted; - }); - } - return event.result; - } - - /** - * Returns an array of event listeners for a given type that can be manipulated - * to add or remove listeners. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} type The event type. - * @returns {Array} The listeners array. - */ - function listeners(type) { - var object = this, - events = object.events || (object.events = {}); - - return _.has(events, type) ? events[type] : (events[type] = []); - } - - /** - * Unregisters a listener for the specified event type(s), - * or unregisters all listeners for the specified event type(s), - * or unregisters all listeners for all event types. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} [type] The event type. - * @param {Function} [listener] The function to unregister. - * @returns {Object} The current instance. - * @example - * - * // unregister a listener for an event type - * bench.off('cycle', listener); - * - * // unregister a listener for multiple event types - * bench.off('start cycle', listener); - * - * // unregister all listeners for an event type - * bench.off('cycle'); - * - * // unregister all listeners for multiple event types - * bench.off('start cycle complete'); - * - * // unregister all listeners for all event types - * bench.off(); - */ - function off(type, listener) { - var object = this, - events = object.events; - - if (!events) { - return object; - } - _.each(type ? type.split(' ') : events, function(listeners, type) { - var index; - if (typeof listeners == 'string') { - type = listeners; - listeners = _.has(events, type) && events[type]; - } - if (listeners) { - if (listener) { - index = _.indexOf(listeners, listener); - if (index > -1) { - listeners.splice(index, 1); - } - } else { - listeners.length = 0; - } - } - }); - return object; - } - - /** - * Registers a listener for the specified event type(s). - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} type The event type. - * @param {Function} listener The function to register. - * @returns {Object} The current instance. - * @example - * - * // register a listener for an event type - * bench.on('cycle', listener); - * - * // register a listener for multiple event types - * bench.on('start cycle', listener); - */ - function on(type, listener) { - var object = this, - events = object.events || (object.events = {}); - - _.each(type.split(' '), function(type) { - (_.has(events, type) - ? events[type] - : (events[type] = []) - ).push(listener); - }); - return object; - } - - /*------------------------------------------------------------------------*/ - - /** - * Aborts the benchmark without recording times. - * - * @memberOf Benchmark - * @returns {Object} The benchmark instance. - */ - function abort() { - var event, - bench = this, - resetting = calledBy.reset; - - if (bench.running) { - event = Event('abort'); - bench.emit(event); - if (!event.cancelled || resetting) { - // Avoid infinite recursion. - calledBy.abort = true; - bench.reset(); - delete calledBy.abort; - - if (support.timeout) { - clearTimeout(bench._timerId); - delete bench._timerId; - } - if (!resetting) { - bench.aborted = true; - bench.running = false; - } - } - } - return bench; - } - - /** - * Creates a new benchmark using the same test and options. - * - * @memberOf Benchmark - * @param {Object} options Options object to overwrite cloned options. - * @returns {Object} The new benchmark instance. - * @example - * - * var bizarro = bench.clone({ - * 'name': 'doppelganger' - * }); - */ - function clone(options) { - var bench = this, - result = new bench.constructor(_.assign({}, bench, options)); - - // Correct the `options` object. - result.options = _.assign({}, cloneDeep(bench.options), cloneDeep(options)); - - // Copy own custom properties. - _.forOwn(bench, function(value, key) { - if (!_.has(result, key)) { - result[key] = cloneDeep(value); - } - }); - - return result; - } - - /** - * Determines if a benchmark is faster than another. - * - * @memberOf Benchmark - * @param {Object} other The benchmark to compare. - * @returns {number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate. - */ - function compare(other) { - var bench = this; - - // Exit early if comparing the same benchmark. - if (bench == other) { - return 0; - } - var critical, - zStat, - sample1 = bench.stats.sample, - sample2 = other.stats.sample, - size1 = sample1.length, - size2 = sample2.length, - maxSize = max(size1, size2), - minSize = min(size1, size2), - u1 = getU(sample1, sample2), - u2 = getU(sample2, sample1), - u = min(u1, u2); - - function getScore(xA, sampleB) { - return _.reduce(sampleB, function(total, xB) { - return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5); - }, 0); - } - - function getU(sampleA, sampleB) { - return _.reduce(sampleA, function(total, xA) { - return total + getScore(xA, sampleB); - }, 0); - } - - function getZ(u) { - return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12); - } - // Reject the null hypothesis the two samples come from the - // same population (i.e. have the same median) if... - if (size1 + size2 > 30) { - // ...the z-stat is greater than 1.96 or less than -1.96 - // http://www.statisticslectures.com/topics/mannwhitneyu/ - zStat = getZ(u); - return abs(zStat) > 1.96 ? (u == u1 ? 1 : -1) : 0; - } - // ...the U value is less than or equal the critical U value. - critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3]; - return u <= critical ? (u == u1 ? 1 : -1) : 0; - } - - /** - * Reset properties and abort if running. - * - * @memberOf Benchmark - * @returns {Object} The benchmark instance. - */ - function reset() { - var bench = this; - if (bench.running && !calledBy.abort) { - // No worries, `reset()` is called within `abort()`. - calledBy.reset = true; - bench.abort(); - delete calledBy.reset; - return bench; - } - var event, - index = 0, - changes = [], - queue = []; - - // A non-recursive solution to check if properties have changed. - // For more information see http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4. - var data = { - 'destination': bench, - 'source': _.assign({}, cloneDeep(bench.constructor.prototype), cloneDeep(bench.options)) - }; - - do { - _.forOwn(data.source, function(value, key) { - var changed, - destination = data.destination, - currValue = destination[key]; - - // Skip pseudo private properties like `_timerId` which could be a - // Java object in environments like RingoJS. - if (key.charAt(0) == '_') { - return; - } - if (value && typeof value == 'object') { - if (_.isArray(value)) { - // Check if an array value has changed to a non-array value. - if (!_.isArray(currValue)) { - changed = currValue = []; - } - // Check if an array has changed its length. - if (currValue.length != value.length) { - changed = currValue = currValue.slice(0, value.length); - currValue.length = value.length; - } - } - // Check if an object has changed to a non-object value. - else if (!currValue || typeof currValue != 'object') { - changed = currValue = {}; - } - // Register a changed object. - if (changed) { - changes.push({ 'destination': destination, 'key': key, 'value': currValue }); - } - queue.push({ 'destination': currValue, 'source': value }); - } - // Register a changed primitive. - else if (value !== currValue && !(value == null || _.isFunction(value))) { - changes.push({ 'destination': destination, 'key': key, 'value': value }); - } - }); - } - while ((data = queue[index++])); - - // If changed emit the `reset` event and if it isn't cancelled reset the benchmark. - if (changes.length && (bench.emit(event = Event('reset')), !event.cancelled)) { - _.each(changes, function(data) { - data.destination[data.key] = data.value; - }); - } - return bench; - } - - /** - * Displays relevant benchmark information when coerced to a string. - * - * @name toString - * @memberOf Benchmark - * @returns {string} A string representation of the benchmark instance. - */ - function toStringBench() { - var bench = this, - error = bench.error, - hz = bench.hz, - id = bench.id, - stats = bench.stats, - size = stats.sample.length, - pm = '\xb1', - result = bench.name || (_.isNaN(id) ? id : ''); - - if (error) { - result += ': ' + join(error); - } else { - result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm + - stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)'; - } - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Clocks the time taken to execute a test per cycle (secs). - * - * @private - * @param {Object} bench The benchmark instance. - * @returns {number} The time taken. - */ - function clock() { - var options = Benchmark.options, - templateData = {}, - timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }]; - - // Lazy define for hi-res timers. - clock = function(clone) { - var deferred; - - if (clone instanceof Deferred) { - deferred = clone; - clone = deferred.benchmark; - } - var bench = clone._original, - stringable = isStringable(bench.fn), - count = bench.count = clone.count, - decompilable = stringable || (support.decompilation && (clone.setup !== _.noop || clone.teardown !== _.noop)), - id = bench.id, - name = bench.name || (typeof id == 'number' ? '' : id), - result = 0; - - // Init `minTime` if needed. - clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime); - - // Compile in setup/teardown functions and the test loop. - // Create a new compiled test, instead of using the cached `bench.compiled`, - // to avoid potential engine optimizations enabled over the life of the test. - var funcBody = deferred - ? 'var d#=this,${fnArg}=d#,m#=d#.benchmark._original,f#=m#.fn,su#=m#.setup,td#=m#.teardown;' + - // When `deferred.cycles` is `0` then... - 'if(!d#.cycles){' + - // set `deferred.fn`, - 'd#.fn=function(){var ${fnArg}=d#;if(typeof f#=="function"){try{${fn}\n}catch(e#){f#(d#)}}else{${fn}\n}};' + - // set `deferred.teardown`, - 'd#.teardown=function(){d#.cycles=0;if(typeof td#=="function"){try{${teardown}\n}catch(e#){td#()}}else{${teardown}\n}};' + - // execute the benchmark's `setup`, - 'if(typeof su#=="function"){try{${setup}\n}catch(e#){su#()}}else{${setup}\n};' + - // start timer, - 't#.start(d#);' + - // and then execute `deferred.fn` and return a dummy object. - '}d#.fn();return{uid:"${uid}"}' - - : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};' + - 'while(i#--){${fn}\n}${end};${teardown}\nreturn{elapsed:r#,uid:"${uid}"}'; - - var compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody), - isEmpty = !(templateData.fn || stringable); - - try { - if (isEmpty) { - // Firefox may remove dead code from `Function#toString` results. - // For more information see http://bugzil.la/536085. - throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.'); - } - else if (!deferred) { - // Pretest to determine if compiled code exits early, usually by a - // rogue `return` statement, by checking for a return object with the uid. - bench.count = 1; - compiled = decompilable && (compiled.call(bench, context, timer) || {}).uid == templateData.uid && compiled; - bench.count = count; - } - } catch(e) { - compiled = null; - clone.error = e || new Error(String(e)); - bench.count = count; - } - // Fallback when a test exits early or errors during pretest. - if (!compiled && !deferred && !isEmpty) { - funcBody = ( - stringable || (decompilable && !clone.error) - ? 'function f#(){${fn}\n}var r#,s#,m#=this,i#=m#.count' - : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count' - ) + - ',n#=t#.ns;${setup}\n${begin};m#.f#=f#;while(i#--){m#.f#()}${end};' + - 'delete m#.f#;${teardown}\nreturn{elapsed:r#}'; - - compiled = createCompiled(bench, decompilable, deferred, funcBody); - - try { - // Pretest one more time to check for errors. - bench.count = 1; - compiled.call(bench, context, timer); - bench.count = count; - delete clone.error; - } - catch(e) { - bench.count = count; - if (!clone.error) { - clone.error = e || new Error(String(e)); - } - } - } - // If no errors run the full test loop. - if (!clone.error) { - compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody); - result = compiled.call(deferred || bench, context, timer).elapsed; - } - return result; - }; - - /*----------------------------------------------------------------------*/ - - /** - * Creates a compiled function from the given function `body`. - */ - function createCompiled(bench, decompilable, deferred, body) { - var fn = bench.fn, - fnArg = deferred ? getFirstArgument(fn) || 'deferred' : ''; - - templateData.uid = uid + uidCounter++; - - _.assign(templateData, { - 'setup': decompilable ? getSource(bench.setup) : interpolate('m#.setup()'), - 'fn': decompilable ? getSource(fn) : interpolate('m#.fn(' + fnArg + ')'), - 'fnArg': fnArg, - 'teardown': decompilable ? getSource(bench.teardown) : interpolate('m#.teardown()') - }); - - // Use API of chosen timer. - if (timer.unit == 'ns') { - _.assign(templateData, { - 'begin': interpolate('s#=n#()'), - 'end': interpolate('r#=n#(s#);r#=r#[0]+(r#[1]/1e9)') - }); - } - else if (timer.unit == 'us') { - if (timer.ns.stop) { - _.assign(templateData, { - 'begin': interpolate('s#=n#.start()'), - 'end': interpolate('r#=n#.microseconds()/1e6') - }); - } else { - _.assign(templateData, { - 'begin': interpolate('s#=n#()'), - 'end': interpolate('r#=(n#()-s#)/1e6') - }); - } - } - else if (timer.ns.now) { - _.assign(templateData, { - 'begin': interpolate('s#=n#.now()'), - 'end': interpolate('r#=(n#.now()-s#)/1e3') - }); - } - else { - _.assign(templateData, { - 'begin': interpolate('s#=new n#().getTime()'), - 'end': interpolate('r#=(new n#().getTime()-s#)/1e3') - }); - } - // Define `timer` methods. - timer.start = createFunction( - interpolate('o#'), - interpolate('var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#') - ); - - timer.stop = createFunction( - interpolate('o#'), - interpolate('var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#') - ); - - // Create compiled test. - return createFunction( - interpolate('window,t#'), - 'var global = window, clearTimeout = global.clearTimeout, setTimeout = global.setTimeout;\n' + - interpolate(body) - ); - } - - /** - * Gets the current timer's minimum resolution (secs). - */ - function getRes(unit) { - var measured, - begin, - count = 30, - divisor = 1e3, - ns = timer.ns, - sample = []; - - // Get average smallest measurable time. - while (count--) { - if (unit == 'us') { - divisor = 1e6; - if (ns.stop) { - ns.start(); - while (!(measured = ns.microseconds())) {} - } else { - begin = ns(); - while (!(measured = ns() - begin)) {} - } - } - else if (unit == 'ns') { - divisor = 1e9; - begin = (begin = ns())[0] + (begin[1] / divisor); - while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) {} - divisor = 1; - } - else if (ns.now) { - begin = ns.now(); - while (!(measured = ns.now() - begin)) {} - } - else { - begin = new ns().getTime(); - while (!(measured = new ns().getTime() - begin)) {} - } - // Check for broken timers. - if (measured > 0) { - sample.push(measured); - } else { - sample.push(Infinity); - break; - } - } - // Convert to seconds. - return getMean(sample) / divisor; - } - - /** - * Interpolates a given template string. - */ - function interpolate(string) { - // Replaces all occurrences of `#` with a unique number and template tokens with content. - return _.template(string.replace(/\#/g, /\d+/.exec(templateData.uid)))(templateData); - } - - /*----------------------------------------------------------------------*/ - - // Detect Chrome's microsecond timer: - // enable benchmarking via the --enable-benchmarking command - // line switch in at least Chrome 7 to use chrome.Interval - try { - if ((timer.ns = new (context.chrome || context.chromium).Interval)) { - timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); - } - } catch(e) {} - - // Detect Node.js's nanosecond resolution timer available in Node.js >= 0.8. - if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') { - timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); - } - // Detect Wade Simmons' Node.js `microtime` module. - if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') { - timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); - } - // Pick timer with highest resolution. - timer = _.minBy(timers, 'res'); - - // Error if there are no working timers. - if (timer.res == Infinity) { - throw new Error('Benchmark.js was unable to find a working timer.'); - } - // Resolve time span required to achieve a percent uncertainty of at most 1%. - // For more information see http://spiff.rit.edu/classes/phys273/uncert/uncert.html. - options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05)); - return clock.apply(null, arguments); - } - - /*------------------------------------------------------------------------*/ - - /** - * Computes stats on benchmark results. - * - * @private - * @param {Object} bench The benchmark instance. - * @param {Object} options The options object. - */ - function compute(bench, options) { - options || (options = {}); - - var async = options.async, - elapsed = 0, - initCount = bench.initCount, - minSamples = bench.minSamples, - queue = [], - sample = bench.stats.sample; - - /** - * Adds a clone to the queue. - */ - function enqueue() { - queue.push(bench.clone({ - '_original': bench, - 'events': { - 'abort': [update], - 'cycle': [update], - 'error': [update], - 'start': [update] - } - })); - } - - /** - * Updates the clone/original benchmarks to keep their data in sync. - */ - function update(event) { - var clone = this, - type = event.type; - - if (bench.running) { - if (type == 'start') { - // Note: `clone.minTime` prop is inited in `clock()`. - clone.count = bench.initCount; - } - else { - if (type == 'error') { - bench.error = clone.error; - } - if (type == 'abort') { - bench.abort(); - bench.emit('cycle'); - } else { - event.currentTarget = event.target = bench; - bench.emit(event); - } - } - } else if (bench.aborted) { - // Clear abort listeners to avoid triggering bench's abort/cycle again. - clone.events.abort.length = 0; - clone.abort(); - } - } - - /** - * Determines if more clones should be queued or if cycling should stop. - */ - function evaluate(event) { - var critical, - df, - mean, - moe, - rme, - sd, - sem, - variance, - clone = event.target, - done = bench.aborted, - now = _.now(), - size = sample.push(clone.times.period), - maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime, - times = bench.times, - varOf = function(sum, x) { return sum + pow(x - mean, 2); }; - - // Exit early for aborted or unclockable tests. - if (done || clone.hz == Infinity) { - maxedOut = !(size = sample.length = queue.length = 0); - } - - if (!done) { - // Compute the sample mean (estimate of the population mean). - mean = getMean(sample); - // Compute the sample variance (estimate of the population variance). - variance = _.reduce(sample, varOf, 0) / (size - 1) || 0; - // Compute the sample standard deviation (estimate of the population standard deviation). - sd = sqrt(variance); - // Compute the standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean). - sem = sd / sqrt(size); - // Compute the degrees of freedom. - df = size - 1; - // Compute the critical value. - critical = tTable[Math.round(df) || 1] || tTable.infinity; - // Compute the margin of error. - moe = sem * critical; - // Compute the relative margin of error. - rme = (moe / mean) * 100 || 0; - - _.assign(bench.stats, { - 'deviation': sd, - 'mean': mean, - 'moe': moe, - 'rme': rme, - 'sem': sem, - 'variance': variance - }); - - // Abort the cycle loop when the minimum sample size has been collected - // and the elapsed time exceeds the maximum time allowed per benchmark. - // We don't count cycle delays toward the max time because delays may be - // increased by browsers that clamp timeouts for inactive tabs. For more - // information see https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs. - if (maxedOut) { - // Reset the `initCount` in case the benchmark is rerun. - bench.initCount = initCount; - bench.running = false; - done = true; - times.elapsed = (now - times.timeStamp) / 1e3; - } - if (bench.hz != Infinity) { - bench.hz = 1 / mean; - times.cycle = mean * bench.count; - times.period = mean; - } - } - // If time permits, increase sample size to reduce the margin of error. - if (queue.length < 2 && !maxedOut) { - enqueue(); - } - // Abort the `invoke` cycle when done. - event.aborted = done; - } - - // Init queue and begin. - enqueue(); - invoke(queue, { - 'name': 'run', - 'args': { 'async': async }, - 'queued': true, - 'onCycle': evaluate, - 'onComplete': function() { bench.emit('complete'); } - }); - } - - /*------------------------------------------------------------------------*/ - - /** - * Cycles a benchmark until a run `count` can be established. - * - * @private - * @param {Object} clone The cloned benchmark instance. - * @param {Object} options The options object. - */ - function cycle(clone, options) { - options || (options = {}); - - var deferred; - if (clone instanceof Deferred) { - deferred = clone; - clone = clone.benchmark; - } - var clocked, - cycles, - divisor, - event, - minTime, - period, - async = options.async, - bench = clone._original, - count = clone.count, - times = clone.times; - - // Continue, if not aborted between cycles. - if (clone.running) { - // `minTime` is set to `Benchmark.options.minTime` in `clock()`. - cycles = ++clone.cycles; - clocked = deferred ? deferred.elapsed : clock(clone); - minTime = clone.minTime; - - if (cycles > bench.cycles) { - bench.cycles = cycles; - } - if (clone.error) { - event = Event('error'); - event.message = clone.error; - clone.emit(event); - if (!event.cancelled) { - clone.abort(); - } - } - } - // Continue, if not errored. - if (clone.running) { - // Compute the time taken to complete last test cycle. - bench.times.cycle = times.cycle = clocked; - // Compute the seconds per operation. - period = bench.times.period = times.period = clocked / count; - // Compute the ops per second. - bench.hz = clone.hz = 1 / period; - // Avoid working our way up to this next time. - bench.initCount = clone.initCount = count; - // Do we need to do another cycle? - clone.running = clocked < minTime; - - if (clone.running) { - // Tests may clock at `0` when `initCount` is a small number, - // to avoid that we set its count to something a bit higher. - if (!clocked && (divisor = divisors[clone.cycles]) != null) { - count = floor(4e6 / divisor); - } - // Calculate how many more iterations it will take to achieve the `minTime`. - if (count <= clone.count) { - count += Math.ceil((minTime - clocked) / period); - } - clone.running = count != Infinity; - } - } - // Should we exit early? - event = Event('cycle'); - clone.emit(event); - if (event.aborted) { - clone.abort(); - } - // Figure out what to do next. - if (clone.running) { - // Start a new cycle. - clone.count = count; - if (deferred) { - clone.compiled.call(deferred, context, timer); - } else if (async) { - delay(clone, function() { cycle(clone, options); }); - } else { - cycle(clone); - } - } - else { - // Fix TraceMonkey bug associated with clock fallbacks. - // For more information see http://bugzil.la/509069. - if (support.browser) { - runScript(uid + '=1;delete ' + uid); - } - // We're done. - clone.emit('complete'); - } - } - - /*------------------------------------------------------------------------*/ - - /** - * Runs the benchmark. - * - * @memberOf Benchmark - * @param {Object} [options={}] Options object. - * @returns {Object} The benchmark instance. - * @example - * - * // basic usage - * bench.run(); - * - * // or with options - * bench.run({ 'async': true }); - */ - function run(options) { - var bench = this, - event = Event('start'); - - // Set `running` to `false` so `reset()` won't call `abort()`. - bench.running = false; - bench.reset(); - bench.running = true; - - bench.count = bench.initCount; - bench.times.timeStamp = _.now(); - bench.emit(event); - - if (!event.cancelled) { - options = { 'async': ((options = options && options.async) == null ? bench.async : options) && support.timeout }; - - // For clones created within `compute()`. - if (bench._original) { - if (bench.defer) { - Deferred(bench); - } else { - cycle(bench, options); - } - } - // For original benchmarks. - else { - compute(bench, options); - } - } - return bench; - } - - /*------------------------------------------------------------------------*/ - - // Firefox 1 erroneously defines variable and argument names of functions on - // the function itself as non-configurable properties with `undefined` values. - // The bugginess continues as the `Benchmark` constructor has an argument - // named `options` and Firefox 1 will not assign a value to `Benchmark.options`, - // making it non-writable in the process, unless it is the first property - // assigned by for-in loop of `_.assign()`. - _.assign(Benchmark, { - - /** - * The default options copied by benchmark instances. - * - * @static - * @memberOf Benchmark - * @type Object - */ - 'options': { - - /** - * A flag to indicate that benchmark cycles will execute asynchronously - * by default. - * - * @memberOf Benchmark.options - * @type boolean - */ - 'async': false, - - /** - * A flag to indicate that the benchmark clock is deferred. - * - * @memberOf Benchmark.options - * @type boolean - */ - 'defer': false, - - /** - * The delay between test cycles (secs). - * @memberOf Benchmark.options - * @type number - */ - 'delay': 0.005, - - /** - * Displayed by `Benchmark#toString` when a `name` is not available - * (auto-generated if absent). - * - * @memberOf Benchmark.options - * @type string - */ - 'id': undefined, - - /** - * The default number of times to execute a test on a benchmark's first cycle. - * - * @memberOf Benchmark.options - * @type number - */ - 'initCount': 1, - - /** - * The maximum time a benchmark is allowed to run before finishing (secs). - * - * Note: Cycle delays aren't counted toward the maximum time. - * - * @memberOf Benchmark.options - * @type number - */ - 'maxTime': 5, - - /** - * The minimum sample size required to perform statistical analysis. - * - * @memberOf Benchmark.options - * @type number - */ - 'minSamples': 5, - - /** - * The time needed to reduce the percent uncertainty of measurement to 1% (secs). - * - * @memberOf Benchmark.options - * @type number - */ - 'minTime': 0, - - /** - * The name of the benchmark. - * - * @memberOf Benchmark.options - * @type string - */ - 'name': undefined, - - /** - * An event listener called when the benchmark is aborted. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onAbort': undefined, - - /** - * An event listener called when the benchmark completes running. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onComplete': undefined, - - /** - * An event listener called after each run cycle. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onCycle': undefined, - - /** - * An event listener called when a test errors. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onError': undefined, - - /** - * An event listener called when the benchmark is reset. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onReset': undefined, - - /** - * An event listener called when the benchmark starts running. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onStart': undefined - }, - - /** - * Platform object with properties describing things like browser name, - * version, and operating system. See [`platform.js`](https://mths.be/platform). - * - * @static - * @memberOf Benchmark - * @type Object - */ - 'platform': context.platform || require('platform') || ({ - 'description': context.navigator && context.navigator.userAgent || null, - 'layout': null, - 'product': null, - 'name': null, - 'manufacturer': null, - 'os': null, - 'prerelease': null, - 'version': null, - 'toString': function() { - return this.description || ''; - } - }), - - /** - * The semantic version number. - * - * @static - * @memberOf Benchmark - * @type string - */ - 'version': '2.1.1' - }); - - _.assign(Benchmark, { - 'filter': filter, - 'formatNumber': formatNumber, - 'invoke': invoke, - 'join': join, - 'runInContext': runInContext, - 'support': support - }); - - // Add lodash methods to Benchmark. - _.each(['each', 'forEach', 'forOwn', 'has', 'indexOf', 'map', 'reduce'], function(methodName) { - Benchmark[methodName] = _[methodName]; - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Benchmark.prototype, { - - /** - * The number of times a test was executed. - * - * @memberOf Benchmark - * @type number - */ - 'count': 0, - - /** - * The number of cycles performed while benchmarking. - * - * @memberOf Benchmark - * @type number - */ - 'cycles': 0, - - /** - * The number of executions per second. - * - * @memberOf Benchmark - * @type number - */ - 'hz': 0, - - /** - * The compiled test function. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'compiled': undefined, - - /** - * The error object if the test failed. - * - * @memberOf Benchmark - * @type Object - */ - 'error': undefined, - - /** - * The test to benchmark. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'fn': undefined, - - /** - * A flag to indicate if the benchmark is aborted. - * - * @memberOf Benchmark - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the benchmark is running. - * - * @memberOf Benchmark - * @type boolean - */ - 'running': false, - - /** - * Compiled into the test and executed immediately **before** the test loop. - * - * @memberOf Benchmark - * @type {Function|string} - * @example - * - * // basic usage - * var bench = Benchmark({ - * 'setup': function() { - * var c = this.count, - * element = document.getElementById('container'); - * while (c--) { - * element.appendChild(document.createElement('div')); - * } - * }, - * 'fn': function() { - * element.removeChild(element.lastChild); - * } - * }); - * - * // compiles to something like: - * var c = this.count, - * element = document.getElementById('container'); - * while (c--) { - * element.appendChild(document.createElement('div')); - * } - * var start = new Date; - * while (count--) { - * element.removeChild(element.lastChild); - * } - * var end = new Date - start; - * - * // or using strings - * var bench = Benchmark({ - * 'setup': '\ - * var a = 0;\n\ - * (function() {\n\ - * (function() {\n\ - * (function() {', - * 'fn': 'a += 1;', - * 'teardown': '\ - * }())\n\ - * }())\n\ - * }())' - * }); - * - * // compiles to something like: - * var a = 0; - * (function() { - * (function() { - * (function() { - * var start = new Date; - * while (count--) { - * a += 1; - * } - * var end = new Date - start; - * }()) - * }()) - * }()) - */ - 'setup': _.noop, - - /** - * Compiled into the test and executed immediately **after** the test loop. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'teardown': _.noop, - - /** - * An object of stats including mean, margin or error, and standard deviation. - * - * @memberOf Benchmark - * @type Object - */ - 'stats': { - - /** - * The margin of error. - * - * @memberOf Benchmark#stats - * @type number - */ - 'moe': 0, - - /** - * The relative margin of error (expressed as a percentage of the mean). - * - * @memberOf Benchmark#stats - * @type number - */ - 'rme': 0, - - /** - * The standard error of the mean. - * - * @memberOf Benchmark#stats - * @type number - */ - 'sem': 0, - - /** - * The sample standard deviation. - * - * @memberOf Benchmark#stats - * @type number - */ - 'deviation': 0, - - /** - * The sample arithmetic mean (secs). - * - * @memberOf Benchmark#stats - * @type number - */ - 'mean': 0, - - /** - * The array of sampled periods. - * - * @memberOf Benchmark#stats - * @type Array - */ - 'sample': [], - - /** - * The sample variance. - * - * @memberOf Benchmark#stats - * @type number - */ - 'variance': 0 - }, - - /** - * An object of timing data including cycle, elapsed, period, start, and stop. - * - * @memberOf Benchmark - * @type Object - */ - 'times': { - - /** - * The time taken to complete the last cycle (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'cycle': 0, - - /** - * The time taken to complete the benchmark (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'elapsed': 0, - - /** - * The time taken to execute the test once (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'period': 0, - - /** - * A timestamp of when the benchmark started (ms). - * - * @memberOf Benchmark#times - * @type number - */ - 'timeStamp': 0 - } - }); - - _.assign(Benchmark.prototype, { - 'abort': abort, - 'clone': clone, - 'compare': compare, - 'emit': emit, - 'listeners': listeners, - 'off': off, - 'on': on, - 'reset': reset, - 'run': run, - 'toString': toStringBench - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Deferred.prototype, { - - /** - * The deferred benchmark instance. - * - * @memberOf Benchmark.Deferred - * @type Object - */ - 'benchmark': null, - - /** - * The number of deferred cycles performed while benchmarking. - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'cycles': 0, - - /** - * The time taken to complete the deferred benchmark (secs). - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'elapsed': 0, - - /** - * A timestamp of when the deferred benchmark started (ms). - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'timeStamp': 0 - }); - - _.assign(Deferred.prototype, { - 'resolve': resolve - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Event.prototype, { - - /** - * A flag to indicate if the emitters listener iteration is aborted. - * - * @memberOf Benchmark.Event - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the default action is cancelled. - * - * @memberOf Benchmark.Event - * @type boolean - */ - 'cancelled': false, - - /** - * The object whose listeners are currently being processed. - * - * @memberOf Benchmark.Event - * @type Object - */ - 'currentTarget': undefined, - - /** - * The return value of the last executed listener. - * - * @memberOf Benchmark.Event - * @type Mixed - */ - 'result': undefined, - - /** - * The object to which the event was originally emitted. - * - * @memberOf Benchmark.Event - * @type Object - */ - 'target': undefined, - - /** - * A timestamp of when the event was created (ms). - * - * @memberOf Benchmark.Event - * @type number - */ - 'timeStamp': 0, - - /** - * The event type. - * - * @memberOf Benchmark.Event - * @type string - */ - 'type': '' - }); - - /*------------------------------------------------------------------------*/ - - /** - * The default options copied by suite instances. - * - * @static - * @memberOf Benchmark.Suite - * @type Object - */ - Suite.options = { - - /** - * The name of the suite. - * - * @memberOf Benchmark.Suite.options - * @type string - */ - 'name': undefined - }; - - /*------------------------------------------------------------------------*/ - - _.assign(Suite.prototype, { - - /** - * The number of benchmarks in the suite. - * - * @memberOf Benchmark.Suite - * @type number - */ - 'length': 0, - - /** - * A flag to indicate if the suite is aborted. - * - * @memberOf Benchmark.Suite - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the suite is running. - * - * @memberOf Benchmark.Suite - * @type boolean - */ - 'running': false - }); - - _.assign(Suite.prototype, { - 'abort': abortSuite, - 'add': add, - 'clone': cloneSuite, - 'emit': emit, - 'filter': filterSuite, - 'join': arrayRef.join, - 'listeners': listeners, - 'off': off, - 'on': on, - 'pop': arrayRef.pop, - 'push': push, - 'reset': resetSuite, - 'run': runSuite, - 'reverse': arrayRef.reverse, - 'shift': shift, - 'slice': slice, - 'sort': arrayRef.sort, - 'splice': arrayRef.splice, - 'unshift': unshift - }); - - /*------------------------------------------------------------------------*/ - - // Expose Deferred, Event, and Suite. - _.assign(Benchmark, { - 'Deferred': Deferred, - 'Event': Event, - 'Suite': Suite - }); - - /*------------------------------------------------------------------------*/ - - // Add lodash methods as Suite methods. - _.each(['each', 'forEach', 'indexOf', 'map', 'reduce'], function(methodName) { - var func = _[methodName]; - Suite.prototype[methodName] = function() { - var args = [this]; - push.apply(args, arguments); - return func.apply(_, args); - }; - }); - - // Avoid array-like object bugs with `Array#shift` and `Array#splice` - // in Firefox < 10 and IE < 9. - _.each(['pop', 'shift', 'splice'], function(methodName) { - var func = arrayRef[methodName]; - - Suite.prototype[methodName] = function() { - var value = this, - result = func.apply(value, arguments); - - if (value.length === 0) { - delete value[0]; - } - return result; - }; - }); - - // Avoid buggy `Array#unshift` in IE < 8 which doesn't return the new - // length of the array. - Suite.prototype.unshift = function() { - var value = this; - unshift.apply(value, arguments); - return value.length; - }; - - return Benchmark; - } - - /*--------------------------------------------------------------------------*/ - - // Export Benchmark. - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Define as an anonymous module so, through path mapping, it can be aliased. - define(['lodash', 'platform'], function(_, platform) { - return runInContext({ - '_': _, - 'platform': platform - }); - }); - } - else { - var Benchmark = runInContext(); - - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - if (freeExports && freeModule) { - // Export for Node.js. - if (moduleExports) { - (freeModule.exports = Benchmark).Benchmark = Benchmark; - } - // Export for CommonJS support. - freeExports.Benchmark = Benchmark; - } - else { - // Export to the global object. - root.Benchmark = Benchmark; - } - } -}.call(this)); diff --git a/third_party/immer/extra/js/lib/immutable.min.js b/third_party/immer/extra/js/lib/immutable.min.js deleted file mode 100644 index 18ffb77bb115..000000000000 --- a/third_party/immer/extra/js/lib/immutable.min.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Immutable=e()}(this,function(){"use strict";function t(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function e(t){return o(t)?t:O(t)}function r(t){return u(t)?t:x(t)}function n(t){return s(t)?t:k(t)}function i(t){return o(t)&&!a(t)?t:A(t)}function o(t){return!(!t||!t[ar])}function u(t){return!(!t||!t[hr])}function s(t){return!(!t||!t[fr])}function a(t){return u(t)||s(t)}function h(t){return!(!t||!t[cr])}function f(t){return t.value=!1,t}function c(t){t&&(t.value=!0)}function _(){}function p(t,e){e=e||0;for(var r=Math.max(0,t.length-e),n=Array(r),i=0;r>i;i++)n[i]=t[i+e];return n}function v(t){return void 0===t.size&&(t.size=t.__iterate(y)),t.size}function l(t,e){if("number"!=typeof e){var r=e>>>0;if(""+r!==e||4294967295===r)return NaN;e=r}return 0>e?v(t)+e:e}function y(){return!0}function d(t,e,r){return(0===t||void 0!==r&&-r>=t)&&(void 0===e||void 0!==r&&e>=r)}function m(t,e){return w(t,e,0)}function g(t,e){return w(t,e,e)}function w(t,e,r){return void 0===t?r:0>t?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}function S(t){this.next=t}function z(t,e,r,n){var i=0===t?e:1===t?r:[e,r];return n?n.value=i:n={value:i,done:!1},n}function I(){return{value:void 0,done:!0}}function b(t){return!!M(t)}function q(t){return t&&"function"==typeof t.next}function D(t){var e=M(t);return e&&e.call(t)}function M(t){var e=t&&(zr&&t[zr]||t[Ir]);return"function"==typeof e?e:void 0}function E(t){return t&&"number"==typeof t.length}function O(t){return null===t||void 0===t?T():o(t)?t.toSeq():C(t)}function x(t){return null===t||void 0===t?T().toKeyedSeq():o(t)?u(t)?t.toSeq():t.fromEntrySeq():B(t)}function k(t){return null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t.toIndexedSeq():W(t)}function A(t){return(null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t:W(t)).toSetSeq()}function j(t){this._array=t,this.size=t.length}function R(t){var e=Object.keys(t);this._object=t,this._keys=e, -this.size=e.length}function U(t){this._iterable=t,this.size=t.length||t.size}function K(t){this._iterator=t,this._iteratorCache=[]}function L(t){return!(!t||!t[qr])}function T(){return Dr||(Dr=new j([]))}function B(t){var e=Array.isArray(t)?new j(t).fromEntrySeq():q(t)?new K(t).fromEntrySeq():b(t)?new U(t).fromEntrySeq():"object"==typeof t?new R(t):void 0;if(!e)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+t);return e}function W(t){var e=J(t);if(!e)throw new TypeError("Expected Array or iterable object of values: "+t);return e}function C(t){var e=J(t)||"object"==typeof t&&new R(t);if(!e)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+t);return e}function J(t){return E(t)?new j(t):q(t)?new K(t):b(t)?new U(t):void 0}function N(t,e,r,n){var i=t._cache;if(i){for(var o=i.length-1,u=0;o>=u;u++){var s=i[r?o-u:u];if(e(s[1],n?s[0]:u,t)===!1)return u+1}return u}return t.__iterateUncached(e,r)}function P(t,e,r,n){var i=t._cache;if(i){var o=i.length-1,u=0;return new S(function(){var t=i[r?o-u:u];return u++>o?I():z(e,n?t[0]:u-1,t[1])})}return t.__iteratorUncached(e,r)}function H(t,e){return e?V(e,t,"",{"":t}):Y(t)}function V(t,e,r,n){return Array.isArray(e)?t.call(n,r,k(e).map(function(r,n){return V(t,r,n,e)})):Q(e)?t.call(n,r,x(e).map(function(r,n){return V(t,r,n,e)})):e}function Y(t){return Array.isArray(t)?k(t).map(Y).toList():Q(t)?x(t).map(Y).toMap():t}function Q(t){return t&&(t.constructor===Object||void 0===t.constructor)}function X(t,e){if(t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1;if("function"==typeof t.valueOf&&"function"==typeof e.valueOf){if(t=t.valueOf(),e=e.valueOf(),t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1}return"function"==typeof t.equals&&"function"==typeof e.equals&&t.equals(e)?!0:!1}function F(t,e){if(t===e)return!0;if(!o(e)||void 0!==t.size&&void 0!==e.size&&t.size!==e.size||void 0!==t.__hash&&void 0!==e.__hash&&t.__hash!==e.__hash||u(t)!==u(e)||s(t)!==s(e)||h(t)!==h(e))return!1;if(0===t.size&&0===e.size)return!0; -var r=!a(t);if(h(t)){var n=t.entries();return e.every(function(t,e){var i=n.next().value;return i&&X(i[1],t)&&(r||X(i[0],e))})&&n.next().done}var i=!1;if(void 0===t.size)if(void 0===e.size)"function"==typeof t.cacheResult&&t.cacheResult();else{i=!0;var f=t;t=e,e=f}var c=!0,_=e.__iterate(function(e,n){return(r?t.has(e):i?X(e,t.get(n,yr)):X(t.get(n,yr),e))?void 0:(c=!1,!1)});return c&&t.size===_}function G(t,e){if(!(this instanceof G))return new G(t,e);if(this._value=t,this.size=void 0===e?1/0:Math.max(0,e),0===this.size){if(Mr)return Mr;Mr=this}}function Z(t,e){if(!t)throw Error(e)}function $(t,e,r){if(!(this instanceof $))return new $(t,e,r);if(Z(0!==r,"Cannot step a Range by 0"),t=t||0,void 0===e&&(e=1/0),r=void 0===r?1:Math.abs(r),t>e&&(r=-r),this._start=t,this._end=e,this._step=r,this.size=Math.max(0,Math.ceil((e-t)/r-1)+1),0===this.size){if(Er)return Er;Er=this}}function tt(){throw TypeError("Abstract")}function et(){}function rt(){}function nt(){}function it(t){return t>>>1&1073741824|3221225471&t}function ot(t){if(t===!1||null===t||void 0===t)return 0;if("function"==typeof t.valueOf&&(t=t.valueOf(),t===!1||null===t||void 0===t))return 0;if(t===!0)return 1;var e=typeof t;if("number"===e){if(t!==t||t===1/0)return 0;var r=0|t;for(r!==t&&(r^=4294967295*t);t>4294967295;)t/=4294967295,r^=t;return it(r)}if("string"===e)return t.length>Kr?ut(t):st(t);if("function"==typeof t.hashCode)return t.hashCode();if("object"===e)return at(t);if("function"==typeof t.toString)return st(""+t);throw Error("Value type "+e+" cannot be hashed.")}function ut(t){var e=Br[t];return void 0===e&&(e=st(t),Tr===Lr&&(Tr=0,Br={}),Tr++,Br[t]=e),e}function st(t){for(var e=0,r=0;t.length>r;r++)e=31*e+t.charCodeAt(r)|0;return it(e)}function at(t){var e;if(jr&&(e=Or.get(t),void 0!==e))return e;if(e=t[Ur],void 0!==e)return e;if(!Ar){if(e=t.propertyIsEnumerable&&t.propertyIsEnumerable[Ur],void 0!==e)return e;if(e=ht(t),void 0!==e)return e}if(e=++Rr,1073741824&Rr&&(Rr=0),jr)Or.set(t,e);else{if(void 0!==kr&&kr(t)===!1)throw Error("Non-extensible objects are not allowed as keys."); -if(Ar)Object.defineProperty(t,Ur,{enumerable:!1,configurable:!1,writable:!1,value:e});else if(void 0!==t.propertyIsEnumerable&&t.propertyIsEnumerable===t.constructor.prototype.propertyIsEnumerable)t.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},t.propertyIsEnumerable[Ur]=e;else{if(void 0===t.nodeType)throw Error("Unable to set a non-enumerable property on object.");t[Ur]=e}}return e}function ht(t){if(t&&t.nodeType>0)switch(t.nodeType){case 1:return t.uniqueID;case 9:return t.documentElement&&t.documentElement.uniqueID}}function ft(t){Z(t!==1/0,"Cannot perform this action with an infinite size.")}function ct(t){return null===t||void 0===t?zt():_t(t)&&!h(t)?t:zt().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function _t(t){return!(!t||!t[Wr])}function pt(t,e){this.ownerID=t,this.entries=e}function vt(t,e,r){this.ownerID=t,this.bitmap=e,this.nodes=r}function lt(t,e,r){this.ownerID=t,this.count=e,this.nodes=r}function yt(t,e,r){this.ownerID=t,this.keyHash=e,this.entries=r}function dt(t,e,r){this.ownerID=t,this.keyHash=e,this.entry=r}function mt(t,e,r){this._type=e,this._reverse=r,this._stack=t._root&&wt(t._root)}function gt(t,e){return z(t,e[0],e[1])}function wt(t,e){return{node:t,index:0,__prev:e}}function St(t,e,r,n){var i=Object.create(Cr);return i.size=t,i._root=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function zt(){return Jr||(Jr=St(0))}function It(t,e,r){var n,i;if(t._root){var o=f(dr),u=f(mr);if(n=bt(t._root,t.__ownerID,0,void 0,e,r,o,u),!u.value)return t;i=t.size+(o.value?r===yr?-1:1:0)}else{if(r===yr)return t;i=1,n=new pt(t.__ownerID,[[e,r]])}return t.__ownerID?(t.size=i,t._root=n,t.__hash=void 0,t.__altered=!0,t):n?St(i,n):zt()}function bt(t,e,r,n,i,o,u,s){return t?t.update(e,r,n,i,o,u,s):o===yr?t:(c(s),c(u),new dt(e,n,[i,o]))}function qt(t){return t.constructor===dt||t.constructor===yt}function Dt(t,e,r,n,i){if(t.keyHash===n)return new yt(e,n,[t.entry,i]);var o,u=(0===r?t.keyHash:t.keyHash>>>r)&lr,s=(0===r?n:n>>>r)&lr,a=u===s?[Dt(t,e,r+pr,n,i)]:(o=new dt(e,n,i), -s>u?[t,o]:[o,t]);return new vt(e,1<o;o++){var u=e[o];i=i.update(t,0,void 0,u[0],u[1])}return i}function Et(t,e,r,n){for(var i=0,o=0,u=Array(r),s=0,a=1,h=e.length;h>s;s++,a<<=1){var f=e[s];void 0!==f&&s!==n&&(i|=a,u[o++]=f)}return new vt(t,i,u)}function Ot(t,e,r,n,i){for(var o=0,u=Array(vr),s=0;0!==r;s++,r>>>=1)u[s]=1&r?e[o++]:void 0;return u[n]=i,new lt(t,o+1,u)}function xt(t,e,n){for(var i=[],u=0;n.length>u;u++){var s=n[u],a=r(s);o(s)||(a=a.map(function(t){return H(t)})),i.push(a)}return jt(t,e,i)}function kt(t,e,r){return t&&t.mergeDeep&&o(e)?t.mergeDeep(e):X(t,e)?t:e}function At(t){return function(e,r,n){if(e&&e.mergeDeepWith&&o(r))return e.mergeDeepWith(t,r);var i=t(e,r,n);return X(e,i)?e:i}}function jt(t,e,r){return r=r.filter(function(t){return 0!==t.size}),0===r.length?t:0!==t.size||t.__ownerID||1!==r.length?t.withMutations(function(t){for(var n=e?function(r,n){t.update(n,yr,function(t){return t===yr?r:e(t,r,n)})}:function(e,r){t.set(r,e)},i=0;r.length>i;i++)r[i].forEach(n)}):t.constructor(r[0])}function Rt(t,e,r,n){var i=t===yr,o=e.next();if(o.done){var u=i?r:t,s=n(u);return s===u?t:s}Z(i||t&&t.set,"invalid keyPath");var a=o.value,h=i?yr:t.get(a,yr),f=Rt(h,e,r,n);return f===h?t:f===yr?t.remove(a):(i?zt():t).set(a,f)}function Ut(t){return t-=t>>1&1431655765,t=(858993459&t)+(t>>2&858993459),t=t+(t>>4)&252645135,t+=t>>8,t+=t>>16,127&t}function Kt(t,e,r,n){var i=n?t:p(t);return i[e]=r,i}function Lt(t,e,r,n){var i=t.length+1;if(n&&e+1===i)return t[e]=r,t;for(var o=Array(i),u=0,s=0;i>s;s++)s===e?(o[s]=r,u=-1):o[s]=t[s+u];return o}function Tt(t,e,r){var n=t.length-1;if(r&&e===n)return t.pop(),t;for(var i=Array(n),o=0,u=0;n>u;u++)u===e&&(o=1),i[u]=t[u+o];return i}function Bt(t){var e=Pt();if(null===t||void 0===t)return e;if(Wt(t))return t;var r=n(t),i=r.size;return 0===i?e:(ft(i),i>0&&vr>i?Nt(0,i,pr,null,new Ct(r.toArray())):e.withMutations(function(t){t.setSize(i),r.forEach(function(e,r){return t.set(r,e)})}))}function Wt(t){ -return!(!t||!t[Vr])}function Ct(t,e){this.array=t,this.ownerID=e}function Jt(t,e){function r(t,e,r){return 0===e?n(t,r):i(t,e,r)}function n(t,r){var n=r===s?a&&a.array:t&&t.array,i=r>o?0:o-r,h=u-r;return h>vr&&(h=vr),function(){if(i===h)return Xr;var t=e?--h:i++;return n&&n[t]}}function i(t,n,i){var s,a=t&&t.array,h=i>o?0:o-i>>n,f=(u-i>>n)+1;return f>vr&&(f=vr),function(){for(;;){if(s){var t=s();if(t!==Xr)return t;s=null}if(h===f)return Xr;var o=e?--f:h++;s=r(a&&a[o],n-pr,i+(o<=t.size||0>e)return t.withMutations(function(t){0>e?Xt(t,e).set(0,r):Xt(t,0,e+1).set(e,r)});e+=t._origin;var n=t._tail,i=t._root,o=f(mr);return e>=Gt(t._capacity)?n=Vt(n,t.__ownerID,0,e,r,o):i=Vt(i,t.__ownerID,t._level,e,r,o),o.value?t.__ownerID?(t._root=i,t._tail=n,t.__hash=void 0,t.__altered=!0,t):Nt(t._origin,t._capacity,t._level,i,n):t}function Vt(t,e,r,n,i,o){var u=n>>>r&lr,s=t&&t.array.length>u;if(!s&&void 0===i)return t;var a;if(r>0){var h=t&&t.array[u],f=Vt(h,e,r-pr,n,i,o);return f===h?t:(a=Yt(t,e),a.array[u]=f,a)}return s&&t.array[u]===i?t:(c(o),a=Yt(t,e),void 0===i&&u===a.array.length-1?a.array.pop():a.array[u]=i,a)}function Yt(t,e){return e&&t&&e===t.ownerID?t:new Ct(t?t.array.slice():[],e)}function Qt(t,e){if(e>=Gt(t._capacity))return t._tail;if(1<e){for(var r=t._root,n=t._level;r&&n>0;)r=r.array[e>>>n&lr],n-=pr;return r}}function Xt(t,e,r){void 0!==e&&(e=0|e),void 0!==r&&(r=0|r);var n=t.__ownerID||new _,i=t._origin,o=t._capacity,u=i+e,s=void 0===r?o:0>r?o+r:i+r;if(u===i&&s===o)return t;if(u>=s)return t.clear();for(var a=t._level,h=t._root,f=0;0>u+f;)h=new Ct(h&&h.array.length?[void 0,h]:[],n),a+=pr,f+=1<=1<p?Qt(t,s-1):p>c?new Ct([],n):v;if(v&&p>c&&o>u&&v.array.length){h=Yt(h,n);for(var y=h,d=a;d>pr;d-=pr){var m=c>>>d&lr;y=y.array[m]=Yt(y.array[m],n)}y.array[c>>>pr&lr]=v}if(o>s&&(l=l&&l.removeAfter(n,0,s)),u>=p)u-=p,s-=p,a=pr,h=null,l=l&&l.removeBefore(n,0,u);else if(u>i||c>p){for(f=0;h;){var g=u>>>a&lr;if(g!==p>>>a&lr)break;g&&(f+=(1<i&&(h=h.removeBefore(n,a,u-f)),h&&c>p&&(h=h.removeAfter(n,a,p-f)),f&&(u-=f,s-=f)}return t.__ownerID?(t.size=s-u,t._origin=u,t._capacity=s,t._level=a,t._root=h,t._tail=l,t.__hash=void 0,t.__altered=!0,t):Nt(u,s,a,h,l)}function Ft(t,e,r){for(var i=[],u=0,s=0;r.length>s;s++){var a=r[s],h=n(a);h.size>u&&(u=h.size),o(a)||(h=h.map(function(t){return H(t)})),i.push(h)}return u>t.size&&(t=t.setSize(u)),jt(t,e,i)}function Gt(t){return vr>t?0:t-1>>>pr<=vr&&u.size>=2*o.size?(i=u.filter(function(t,e){return void 0!==t&&s!==e}),n=i.toKeyedSeq().map(function(t){return t[0]}).flip().toMap(),t.__ownerID&&(n.__ownerID=i.__ownerID=t.__ownerID)):(n=o.remove(e),i=s===u.size-1?u.pop():u.set(s,void 0))}else if(a){if(r===u.get(s)[1])return t;n=o,i=u.set(s,[e,r])}else n=o.set(e,u.size),i=u.set(u.size,[e,r]);return t.__ownerID?(t.size=n.size,t._map=n,t._list=i,t.__hash=void 0,t):te(n,i)}function ne(t,e){this._iter=t,this._useKeys=e,this.size=t.size}function ie(t){this._iter=t,this.size=t.size}function oe(t){this._iter=t,this.size=t.size}function ue(t){this._iter=t,this.size=t.size}function se(t){var e=Ee(t);return e._iter=t,e.size=t.size,e.flip=function(){return t},e.reverse=function(){var e=t.reverse.apply(this); -return e.flip=function(){return t.reverse()},e},e.has=function(e){return t.includes(e)},e.includes=function(e){return t.has(e)},e.cacheResult=Oe,e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t,r){return e(r,t,n)!==!1},r)},e.__iteratorUncached=function(e,r){if(e===Sr){var n=t.__iterator(e,r);return new S(function(){var t=n.next();if(!t.done){var e=t.value[0];t.value[0]=t.value[1],t.value[1]=e}return t})}return t.__iterator(e===wr?gr:wr,r)},e}function ae(t,e,r){var n=Ee(t);return n.size=t.size,n.has=function(e){return t.has(e)},n.get=function(n,i){var o=t.get(n,yr);return o===yr?i:e.call(r,o,n,t)},n.__iterateUncached=function(n,i){var o=this;return t.__iterate(function(t,i,u){return n(e.call(r,t,i,u),i,o)!==!1},i)},n.__iteratorUncached=function(n,i){var o=t.__iterator(Sr,i);return new S(function(){var i=o.next();if(i.done)return i;var u=i.value,s=u[0];return z(n,s,e.call(r,u[1],s,t),i)})},n}function he(t,e){var r=Ee(t);return r._iter=t,r.size=t.size,r.reverse=function(){return t},t.flip&&(r.flip=function(){var e=se(t);return e.reverse=function(){return t.flip()},e}),r.get=function(r,n){return t.get(e?r:-1-r,n)},r.has=function(r){return t.has(e?r:-1-r)},r.includes=function(e){return t.includes(e)},r.cacheResult=Oe,r.__iterate=function(e,r){var n=this;return t.__iterate(function(t,r){return e(t,r,n)},!r)},r.__iterator=function(e,r){return t.__iterator(e,!r)},r}function fe(t,e,r,n){var i=Ee(t);return n&&(i.has=function(n){var i=t.get(n,yr);return i!==yr&&!!e.call(r,i,n,t)},i.get=function(n,i){var o=t.get(n,yr);return o!==yr&&e.call(r,o,n,t)?o:i}),i.__iterateUncached=function(i,o){var u=this,s=0;return t.__iterate(function(t,o,a){return e.call(r,t,o,a)?(s++,i(t,n?o:s-1,u)):void 0},o),s},i.__iteratorUncached=function(i,o){var u=t.__iterator(Sr,o),s=0;return new S(function(){for(;;){var o=u.next();if(o.done)return o;var a=o.value,h=a[0],f=a[1];if(e.call(r,f,h,t))return z(i,n?h:s++,f,o)}})},i}function ce(t,e,r){var n=ct().asMutable();return t.__iterate(function(i,o){n.update(e.call(r,i,o,t),0,function(t){ -return t+1})}),n.asImmutable()}function _e(t,e,r){var n=u(t),i=(h(t)?Zt():ct()).asMutable();t.__iterate(function(o,u){i.update(e.call(r,o,u,t),function(t){return t=t||[],t.push(n?[u,o]:o),t})});var o=Me(t);return i.map(function(e){return be(t,o(e))})}function pe(t,e,r,n){var i=t.size;if(void 0!==e&&(e=0|e),void 0!==r&&(r=r===1/0?i:0|r),d(e,r,i))return t;var o=m(e,i),u=g(r,i);if(o!==o||u!==u)return pe(t.toSeq().cacheResult(),e,r,n);var s,a=u-o;a===a&&(s=0>a?0:a);var h=Ee(t);return h.size=0===s?s:t.size&&s||void 0,!n&&L(t)&&s>=0&&(h.get=function(e,r){return e=l(this,e),e>=0&&s>e?t.get(e+o,r):r}),h.__iterateUncached=function(e,r){var i=this;if(0===s)return 0;if(r)return this.cacheResult().__iterate(e,r);var u=0,a=!0,h=0;return t.__iterate(function(t,r){return a&&(a=u++s)return I();var t=i.next();return n||e===wr?t:e===gr?z(e,a-1,void 0,t):z(e,a-1,t.value[1],t)})},h}function ve(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterate(n,i);var u=0;return t.__iterate(function(t,i,s){return e.call(r,t,i,s)&&++u&&n(t,i,o)}),u},n.__iteratorUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterator(n,i);var u=t.__iterator(Sr,i),s=!0;return new S(function(){if(!s)return I();var t=u.next();if(t.done)return t;var i=t.value,a=i[0],h=i[1];return e.call(r,h,a,o)?n===Sr?t:z(n,a,h,t):(s=!1,I())})},n}function le(t,e,r,n){var i=Ee(t);return i.__iterateUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,a=0;return t.__iterate(function(t,o,h){return s&&(s=e.call(r,t,o,h))?void 0:(a++,i(t,n?o:a-1,u))}),a},i.__iteratorUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterator(i,o);var s=t.__iterator(Sr,o),a=!0,h=0;return new S(function(){var t,o,f;do{if(t=s.next(),t.done)return n||i===wr?t:i===gr?z(i,h++,void 0,t):z(i,h++,t.value[1],t); -var c=t.value;o=c[0],f=c[1],a&&(a=e.call(r,f,o,u))}while(a);return i===Sr?t:z(i,o,f,t)})},i}function ye(t,e){var n=u(t),i=[t].concat(e).map(function(t){return o(t)?n&&(t=r(t)):t=n?B(t):W(Array.isArray(t)?t:[t]),t}).filter(function(t){return 0!==t.size});if(0===i.length)return t;if(1===i.length){var a=i[0];if(a===t||n&&u(a)||s(t)&&s(a))return a}var h=new j(i);return n?h=h.toKeyedSeq():s(t)||(h=h.toSetSeq()),h=h.flatten(!0),h.size=i.reduce(function(t,e){if(void 0!==t){var r=e.size;if(void 0!==r)return t+r}},0),h}function de(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){function u(t,h){var f=this;t.__iterate(function(t,i){return(!e||e>h)&&o(t)?u(t,h+1):n(t,r?i:s++,f)===!1&&(a=!0),!a},i)}var s=0,a=!1;return u(t,0),s},n.__iteratorUncached=function(n,i){var u=t.__iterator(n,i),s=[],a=0;return new S(function(){for(;u;){var t=u.next();if(t.done===!1){var h=t.value;if(n===Sr&&(h=h[1]),e&&!(e>s.length)||!o(h))return r?t:z(n,a++,h,t);s.push(u),u=h.__iterator(n,i)}else u=s.pop()}return I()})},n}function me(t,e,r){var n=Me(t);return t.toSeq().map(function(i,o){return n(e.call(r,i,o,t))}).flatten(!0)}function ge(t,e){var r=Ee(t);return r.size=t.size&&2*t.size-1,r.__iterateUncached=function(r,n){var i=this,o=0;return t.__iterate(function(t,n){return(!o||r(e,o++,i)!==!1)&&r(t,o++,i)!==!1},n),o},r.__iteratorUncached=function(r,n){var i,o=t.__iterator(wr,n),u=0;return new S(function(){return(!i||u%2)&&(i=o.next(),i.done)?i:u%2?z(r,u++,e):z(r,u++,i.value,i)})},r}function we(t,e,r){e||(e=xe);var n=u(t),i=0,o=t.toSeq().map(function(e,n){return[n,e,i++,r?r(e,n,t):e]}).toArray();return o.sort(function(t,r){return e(t[3],r[3])||t[2]-r[2]}).forEach(n?function(t,e){o[e].length=2}:function(t,e){o[e]=t[1]}),n?x(o):s(t)?k(o):A(o)}function Se(t,e,r){if(e||(e=xe),r){var n=t.toSeq().map(function(e,n){return[e,r(e,n,t)]}).reduce(function(t,r){return ze(e,t[1],r[1])?r:t});return n&&n[0]}return t.reduce(function(t,r){return ze(e,t,r)?r:t})}function ze(t,e,r){var n=t(r,e);return 0===n&&r!==e&&(void 0===r||null===r||r!==r)||n>0}function Ie(t,r,n){ -var i=Ee(t);return i.size=new j(n).map(function(t){return t.size}).min(),i.__iterate=function(t,e){for(var r,n=this.__iterator(wr,e),i=0;!(r=n.next()).done&&t(r.value,i++,this)!==!1;);return i},i.__iteratorUncached=function(t,i){var o=n.map(function(t){return t=e(t),D(i?t.reverse():t)}),u=0,s=!1;return new S(function(){var e;return s||(e=o.map(function(t){return t.next()}),s=e.some(function(t){return t.done})),s?I():z(t,u++,r.apply(null,e.map(function(t){return t.value})))})},i}function be(t,e){return L(t)?e:t.constructor(e)}function qe(t){if(t!==Object(t))throw new TypeError("Expected [K, V] tuple: "+t)}function De(t){return ft(t.size),v(t)}function Me(t){return u(t)?r:s(t)?n:i}function Ee(t){return Object.create((u(t)?x:s(t)?k:A).prototype)}function Oe(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):O.prototype.cacheResult.call(this)}function xe(t,e){return t>e?1:e>t?-1:0}function ke(t){var r=D(t);if(!r){if(!E(t))throw new TypeError("Expected iterable or array-like: "+t);r=D(e(t))}return r}function Ae(t,e){var r,n=function(o){if(o instanceof n)return o;if(!(this instanceof n))return new n(o);if(!r){r=!0;var u=Object.keys(t);Ue(i,u),i.size=u.length,i._name=e,i._keys=u,i._defaultValues=t}this._map=ct(o)},i=n.prototype=Object.create(Gr);return i.constructor=n,n}function je(t,e,r){var n=Object.create(Object.getPrototypeOf(t));return n._map=e,n.__ownerID=r,n}function Re(t){return t._name||t.constructor.name||"Record"}function Ue(t,e){try{e.forEach(Ke.bind(void 0,t))}catch(r){}}function Ke(t,e){Object.defineProperty(t,e,{get:function(){return this.get(e)},set:function(t){Z(this.__ownerID,"Cannot set on an immutable record."),this.set(e,t)}})}function Le(t){return null===t||void 0===t?Ce():Te(t)&&!h(t)?t:Ce().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Te(t){return!(!t||!t[Zr])}function Be(t,e){return t.__ownerID?(t.size=e.size,t._map=e,t):e===t._map?t:0===e.size?t.__empty():t.__make(e)}function We(t,e){var r=Object.create($r); -return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function Ce(){return tn||(tn=We(zt()))}function Je(t){return null===t||void 0===t?He():Ne(t)?t:He().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Ne(t){return Te(t)&&h(t)}function Pe(t,e){var r=Object.create(en);return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function He(){return rn||(rn=Pe(ee()))}function Ve(t){return null===t||void 0===t?Xe():Ye(t)?t:Xe().unshiftAll(t)}function Ye(t){return!(!t||!t[nn])}function Qe(t,e,r,n){var i=Object.create(on);return i.size=t,i._head=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function Xe(){return un||(un=Qe(0))}function Fe(t,e){var r=function(r){t.prototype[r]=e[r]};return Object.keys(e).forEach(r),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(e).forEach(r),t}function Ge(t,e){return e}function Ze(t,e){return[e,t]}function $e(t){return function(){return!t.apply(this,arguments)}}function tr(t){return function(){return-t.apply(this,arguments)}}function er(t){return"string"==typeof t?JSON.stringify(t):t+""}function rr(){return p(arguments)}function nr(t,e){return e>t?1:t>e?-1:0}function ir(t){if(t.size===1/0)return 0;var e=h(t),r=u(t),n=e?1:0,i=t.__iterate(r?e?function(t,e){n=31*n+ur(ot(t),ot(e))|0}:function(t,e){n=n+ur(ot(t),ot(e))|0}:e?function(t){n=31*n+ot(t)|0}:function(t){n=n+ot(t)|0});return or(i,n)}function or(t,e){return e=xr(e,3432918353),e=xr(e<<15|e>>>-15,461845907),e=xr(e<<13|e>>>-13,5),e=(e+3864292196|0)^t,e=xr(e^e>>>16,2246822507),e=xr(e^e>>>13,3266489909),e=it(e^e>>>16)}function ur(t,e){return t^e+2654435769+(t<<6)+(t>>2)|0}var sr=Array.prototype.slice;t(r,e),t(n,e),t(i,e),e.isIterable=o,e.isKeyed=u,e.isIndexed=s,e.isAssociative=a,e.isOrdered=h,e.Keyed=r,e.Indexed=n,e.Set=i;var ar="@@__IMMUTABLE_ITERABLE__@@",hr="@@__IMMUTABLE_KEYED__@@",fr="@@__IMMUTABLE_INDEXED__@@",cr="@@__IMMUTABLE_ORDERED__@@",_r="delete",pr=5,vr=1<=i;i++)if(t(r[e?n-i:i],i,this)===!1)return i+1;return i},j.prototype.__iterator=function(t,e){var r=this._array,n=r.length-1,i=0;return new S(function(){return i>n?I():z(t,i,r[e?n-i++:i++])})},t(R,x),R.prototype.get=function(t,e){return void 0===e||this.has(t)?this._object[t]:e},R.prototype.has=function(t){return this._object.hasOwnProperty(t)},R.prototype.__iterate=function(t,e){for(var r=this._object,n=this._keys,i=n.length-1,o=0;i>=o;o++){var u=n[e?i-o:o];if(t(r[u],u,this)===!1)return o+1}return o},R.prototype.__iterator=function(t,e){var r=this._object,n=this._keys,i=n.length-1,o=0;return new S(function(){var u=n[e?i-o:o];return o++>i?I():z(t,u,r[u])})},R.prototype[cr]=!0,t(U,k),U.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e); -var r=this._iterable,n=D(r),i=0;if(q(n))for(var o;!(o=n.next()).done&&t(o.value,i++,this)!==!1;);return i},U.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterable,n=D(r);if(!q(n))return new S(I);var i=0;return new S(function(){var e=n.next();return e.done?e:z(t,i++,e.value)})},t(K,k),K.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e);for(var r=this._iterator,n=this._iteratorCache,i=0;n.length>i;)if(t(n[i],i++,this)===!1)return i;for(var o;!(o=r.next()).done;){var u=o.value;if(n[i]=u,t(u,i++,this)===!1)break}return i},K.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterator,n=this._iteratorCache,i=0;return new S(function(){if(i>=n.length){var e=r.next();if(e.done)return e;n[i]=e.value}return z(t,i,n[i++])})};var Dr;t(G,k),G.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},G.prototype.get=function(t,e){return this.has(t)?this._value:e},G.prototype.includes=function(t){return X(this._value,t)},G.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:new G(this._value,g(e,r)-m(t,r))},G.prototype.reverse=function(){return this},G.prototype.indexOf=function(t){return X(this._value,t)?0:-1},G.prototype.lastIndexOf=function(t){return X(this._value,t)?this.size:-1},G.prototype.__iterate=function(t,e){for(var r=0;this.size>r;r++)if(t(this._value,r,this)===!1)return r+1;return r},G.prototype.__iterator=function(t,e){var r=this,n=0;return new S(function(){return r.size>n?z(t,n++,r._value):I()})},G.prototype.equals=function(t){return t instanceof G?X(this._value,t._value):F(t)};var Mr;t($,k),$.prototype.toString=function(){return 0===this.size?"Range []":"Range [ "+this._start+"..."+this._end+(1!==this._step?" by "+this._step:"")+" ]"},$.prototype.get=function(t,e){return this.has(t)?this._start+l(this,t)*this._step:e},$.prototype.includes=function(t){var e=(t-this._start)/this._step;return e>=0&&this.size>e&&e===Math.floor(e); -},$.prototype.slice=function(t,e){return d(t,e,this.size)?this:(t=m(t,this.size),e=g(e,this.size),t>=e?new $(0,0):new $(this.get(t,this._end),this.get(e,this._end),this._step))},$.prototype.indexOf=function(t){var e=t-this._start;if(e%this._step===0){var r=e/this._step;if(r>=0&&this.size>r)return r}return-1},$.prototype.lastIndexOf=function(t){return this.indexOf(t)},$.prototype.__iterate=function(t,e){for(var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;r>=o;o++){if(t(i,o,this)===!1)return o+1;i+=e?-n:n}return o},$.prototype.__iterator=function(t,e){var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;return new S(function(){var u=i;return i+=e?-n:n,o>r?I():z(t,o++,u)})},$.prototype.equals=function(t){return t instanceof $?this._start===t._start&&this._end===t._end&&this._step===t._step:F(this,t)};var Er;t(tt,e),t(et,tt),t(rt,tt),t(nt,tt),tt.Keyed=et,tt.Indexed=rt,tt.Set=nt;var Or,xr="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(t,e){t=0|t,e=0|e;var r=65535&t,n=65535&e;return r*n+((t>>>16)*n+r*(e>>>16)<<16>>>0)|0},kr=Object.isExtensible,Ar=function(){try{return Object.defineProperty({},"@",{}),!0}catch(t){return!1}}(),jr="function"==typeof WeakMap;jr&&(Or=new WeakMap);var Rr=0,Ur="__immutablehash__";"function"==typeof Symbol&&(Ur=Symbol(Ur));var Kr=16,Lr=255,Tr=0,Br={};t(ct,et),ct.of=function(){var t=sr.call(arguments,0);return zt().withMutations(function(e){for(var r=0;t.length>r;r+=2){if(r+1>=t.length)throw Error("Missing value for key: "+t[r]);e.set(t[r],t[r+1])}})},ct.prototype.toString=function(){return this.__toString("Map {","}")},ct.prototype.get=function(t,e){return this._root?this._root.get(0,void 0,t,e):e},ct.prototype.set=function(t,e){return It(this,t,e)},ct.prototype.setIn=function(t,e){return this.updateIn(t,yr,function(){return e})},ct.prototype.remove=function(t){return It(this,t,yr)},ct.prototype.deleteIn=function(t){return this.updateIn(t,function(){return yr})},ct.prototype.update=function(t,e,r){return 1===arguments.length?t(this):this.updateIn([t],e,r); -},ct.prototype.updateIn=function(t,e,r){r||(r=e,e=void 0);var n=Rt(this,ke(t),e,r);return n===yr?void 0:n},ct.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):zt()},ct.prototype.merge=function(){return xt(this,void 0,arguments)},ct.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return xt(this,t,e)},ct.prototype.mergeIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.merge?t.merge.apply(t,e):e[e.length-1]})},ct.prototype.mergeDeep=function(){return xt(this,kt,arguments)},ct.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return xt(this,At(t),e)},ct.prototype.mergeDeepIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.mergeDeep?t.mergeDeep.apply(t,e):e[e.length-1]})},ct.prototype.sort=function(t){return Zt(we(this,t))},ct.prototype.sortBy=function(t,e){return Zt(we(this,e,t))},ct.prototype.withMutations=function(t){var e=this.asMutable();return t(e),e.wasAltered()?e.__ensureOwner(this.__ownerID):this},ct.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new _)},ct.prototype.asImmutable=function(){return this.__ensureOwner()},ct.prototype.wasAltered=function(){return this.__altered},ct.prototype.__iterator=function(t,e){return new mt(this,t,e)},ct.prototype.__iterate=function(t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},ct.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?St(this.size,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},ct.isMap=_t;var Wr="@@__IMMUTABLE_MAP__@@",Cr=ct.prototype;Cr[Wr]=!0,Cr[_r]=Cr.remove,Cr.removeIn=Cr.deleteIn,pt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},pt.prototype.update=function(t,e,r,n,i,o,u){for(var s=i===yr,a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++); -var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),!s||1!==a.length){if(!_&&!s&&a.length>=Nr)return Mt(t,a,n,i);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new pt(t,l)}},vt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=1<<((0===t?e:e>>>t)&lr),o=this.bitmap;return 0===(o&i)?n:this.nodes[Ut(o&i-1)].get(t+pr,e,r,n)},vt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=1<=Pr)return Ot(t,_,h,s,v);if(f&&!v&&2===_.length&&qt(_[1^c]))return _[1^c];if(f&&v&&1===_.length&&qt(v))return v;var l=t&&t===this.ownerID,y=f?v?h:h^a:h|a,d=f?v?Kt(_,c,v,l):Tt(_,c,l):Lt(_,c,v,l);return l?(this.bitmap=y,this.nodes=d,this):new vt(t,y,d)},lt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=(0===t?e:e>>>t)&lr,o=this.nodes[i];return o?o.get(t+pr,e,r,n):n},lt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=i===yr,h=this.nodes,f=h[s];if(a&&!f)return this;var c=bt(f,t,e+pr,r,n,i,o,u);if(c===f)return this;var _=this.count;if(f){if(!c&&(_--,Hr>_))return Et(t,h,_,s)}else _++;var p=t&&t===this.ownerID,v=Kt(h,s,c,p);return p?(this.count=_,this.nodes=v,this):new lt(t,_,v)},yt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},yt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=i===yr;if(r!==this.keyHash)return s?this:(c(u),c(o),Dt(this,t,e,r,[n,i]));for(var a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++);var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),s&&2===f)return new dt(t,this.keyHash,a[1^h]);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new yt(t,this.keyHash,l)},dt.prototype.get=function(t,e,r,n){return X(r,this.entry[0])?this.entry[1]:n; -},dt.prototype.update=function(t,e,r,n,i,o,u){var s=i===yr,a=X(n,this.entry[0]);return(a?i===this.entry[1]:s)?this:(c(u),s?void c(o):a?t&&t===this.ownerID?(this.entry[1]=i,this):new dt(t,this.keyHash,[n,i]):(c(o),Dt(this,t,e,ot(n),[n,i])))},pt.prototype.iterate=yt.prototype.iterate=function(t,e){for(var r=this.entries,n=0,i=r.length-1;i>=n;n++)if(t(r[e?i-n:n])===!1)return!1},vt.prototype.iterate=lt.prototype.iterate=function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++){var o=r[e?i-n:n];if(o&&o.iterate(t,e)===!1)return!1}},dt.prototype.iterate=function(t,e){return t(this.entry)},t(mt,S),mt.prototype.next=function(){for(var t=this._type,e=this._stack;e;){var r,n=e.node,i=e.index++;if(n.entry){if(0===i)return gt(t,n.entry)}else if(n.entries){if(r=n.entries.length-1,r>=i)return gt(t,n.entries[this._reverse?r-i:i])}else if(r=n.nodes.length-1,r>=i){var o=n.nodes[this._reverse?r-i:i];if(o){if(o.entry)return gt(t,o.entry);e=this._stack=wt(o,e)}continue}e=this._stack=this._stack.__prev}return I()};var Jr,Nr=vr/4,Pr=vr/2,Hr=vr/4;t(Bt,rt),Bt.of=function(){return this(arguments)},Bt.prototype.toString=function(){return this.__toString("List [","]")},Bt.prototype.get=function(t,e){if(t=l(this,t),t>=0&&this.size>t){t+=this._origin;var r=Qt(this,t);return r&&r.array[t&lr]}return e},Bt.prototype.set=function(t,e){return Ht(this,t,e)},Bt.prototype.remove=function(t){return this.has(t)?0===t?this.shift():t===this.size-1?this.pop():this.splice(t,1):this},Bt.prototype.insert=function(t,e){return this.splice(t,0,e)},Bt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=pr,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):Pt()},Bt.prototype.push=function(){var t=arguments,e=this.size;return this.withMutations(function(r){Xt(r,0,e+t.length);for(var n=0;t.length>n;n++)r.set(e+n,t[n])})},Bt.prototype.pop=function(){return Xt(this,0,-1)},Bt.prototype.unshift=function(){var t=arguments;return this.withMutations(function(e){Xt(e,-t.length);for(var r=0;t.length>r;r++)e.set(r,t[r]); -})},Bt.prototype.shift=function(){return Xt(this,1)},Bt.prototype.merge=function(){return Ft(this,void 0,arguments)},Bt.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return Ft(this,t,e)},Bt.prototype.mergeDeep=function(){return Ft(this,kt,arguments)},Bt.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return Ft(this,At(t),e)},Bt.prototype.setSize=function(t){return Xt(this,0,t)},Bt.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:Xt(this,m(t,r),g(e,r))},Bt.prototype.__iterator=function(t,e){var r=0,n=Jt(this,e);return new S(function(){var e=n();return e===Xr?I():z(t,r++,e)})},Bt.prototype.__iterate=function(t,e){for(var r,n=0,i=Jt(this,e);(r=i())!==Xr&&t(r,n++,this)!==!1;);return n},Bt.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Nt(this._origin,this._capacity,this._level,this._root,this._tail,t,this.__hash):(this.__ownerID=t,this)},Bt.isList=Wt;var Vr="@@__IMMUTABLE_LIST__@@",Yr=Bt.prototype;Yr[Vr]=!0,Yr[_r]=Yr.remove,Yr.setIn=Cr.setIn,Yr.deleteIn=Yr.removeIn=Cr.removeIn,Yr.update=Cr.update,Yr.updateIn=Cr.updateIn,Yr.mergeIn=Cr.mergeIn,Yr.mergeDeepIn=Cr.mergeDeepIn,Yr.withMutations=Cr.withMutations,Yr.asMutable=Cr.asMutable,Yr.asImmutable=Cr.asImmutable,Yr.wasAltered=Cr.wasAltered,Ct.prototype.removeBefore=function(t,e,r){if(r===e?1<>>e&lr;if(n>=this.array.length)return new Ct([],t);var i,o=0===n;if(e>0){var u=this.array[n];if(i=u&&u.removeBefore(t,e-pr,r),i===u&&o)return this}if(o&&!i)return this;var s=Yt(this,t);if(!o)for(var a=0;n>a;a++)s.array[a]=void 0;return i&&(s.array[n]=i),s},Ct.prototype.removeAfter=function(t,e,r){if(r===(e?1<>>e&lr;if(n>=this.array.length)return this;var i;if(e>0){var o=this.array[n];if(i=o&&o.removeAfter(t,e-pr,r),i===o&&n===this.array.length-1)return this}var u=Yt(this,t);return u.array.splice(n+1),i&&(u.array[n]=i),u};var Qr,Xr={};t(Zt,ct),Zt.of=function(){return this(arguments)},Zt.prototype.toString=function(){return this.__toString("OrderedMap {","}"); -},Zt.prototype.get=function(t,e){var r=this._map.get(t);return void 0!==r?this._list.get(r)[1]:e},Zt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):ee()},Zt.prototype.set=function(t,e){return re(this,t,e)},Zt.prototype.remove=function(t){return re(this,t,yr)},Zt.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Zt.prototype.__iterate=function(t,e){var r=this;return this._list.__iterate(function(e){return e&&t(e[1],e[0],r)},e)},Zt.prototype.__iterator=function(t,e){return this._list.fromEntrySeq().__iterator(t,e)},Zt.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t),r=this._list.__ensureOwner(t);return t?te(e,r,t,this.__hash):(this.__ownerID=t,this._map=e,this._list=r,this)},Zt.isOrderedMap=$t,Zt.prototype[cr]=!0,Zt.prototype[_r]=Zt.prototype.remove;var Fr;t(ne,x),ne.prototype.get=function(t,e){return this._iter.get(t,e)},ne.prototype.has=function(t){return this._iter.has(t)},ne.prototype.valueSeq=function(){return this._iter.valueSeq()},ne.prototype.reverse=function(){var t=this,e=he(this,!0);return this._useKeys||(e.valueSeq=function(){return t._iter.toSeq().reverse()}),e},ne.prototype.map=function(t,e){var r=this,n=ae(this,t,e);return this._useKeys||(n.valueSeq=function(){return r._iter.toSeq().map(t,e)}),n},ne.prototype.__iterate=function(t,e){var r,n=this;return this._iter.__iterate(this._useKeys?function(e,r){return t(e,r,n)}:(r=e?De(this):0,function(i){return t(i,e?--r:r++,n)}),e)},ne.prototype.__iterator=function(t,e){if(this._useKeys)return this._iter.__iterator(t,e);var r=this._iter.__iterator(wr,e),n=e?De(this):0;return new S(function(){var i=r.next();return i.done?i:z(t,e?--n:n++,i.value,i)})},ne.prototype[cr]=!0,t(ie,k),ie.prototype.includes=function(t){return this._iter.includes(t)},ie.prototype.__iterate=function(t,e){var r=this,n=0;return this._iter.__iterate(function(e){return t(e,n++,r)},e)},ie.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e),n=0; -return new S(function(){var e=r.next();return e.done?e:z(t,n++,e.value,e)})},t(oe,A),oe.prototype.has=function(t){return this._iter.includes(t)},oe.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){return t(e,e,r)},e)},oe.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){var e=r.next();return e.done?e:z(t,e.value,e.value,e)})},t(ue,x),ue.prototype.entrySeq=function(){return this._iter.toSeq()},ue.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){if(e){qe(e);var n=o(e);return t(n?e.get(1):e[1],n?e.get(0):e[0],r)}},e)},ue.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){for(;;){var e=r.next();if(e.done)return e;var n=e.value;if(n){qe(n);var i=o(n);return z(t,i?n.get(0):n[0],i?n.get(1):n[1],e)}}})},ie.prototype.cacheResult=ne.prototype.cacheResult=oe.prototype.cacheResult=ue.prototype.cacheResult=Oe,t(Ae,et),Ae.prototype.toString=function(){return this.__toString(Re(this)+" {","}")},Ae.prototype.has=function(t){return this._defaultValues.hasOwnProperty(t)},Ae.prototype.get=function(t,e){if(!this.has(t))return e;var r=this._defaultValues[t];return this._map?this._map.get(t,r):r},Ae.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var t=this.constructor;return t._empty||(t._empty=je(this,zt()))},Ae.prototype.set=function(t,e){if(!this.has(t))throw Error('Cannot set unknown key "'+t+'" on '+Re(this));if(this._map&&!this._map.has(t)){var r=this._defaultValues[t];if(e===r)return this}var n=this._map&&this._map.set(t,e);return this.__ownerID||n===this._map?this:je(this,n)},Ae.prototype.remove=function(t){if(!this.has(t))return this;var e=this._map&&this._map.remove(t);return this.__ownerID||e===this._map?this:je(this,e)},Ae.prototype.wasAltered=function(){return this._map.wasAltered()},Ae.prototype.__iterator=function(t,e){var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterator(t,e)},Ae.prototype.__iterate=function(t,e){ -var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterate(t,e)},Ae.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map&&this._map.__ensureOwner(t);return t?je(this,e,t):(this.__ownerID=t,this._map=e,this)};var Gr=Ae.prototype;Gr[_r]=Gr.remove,Gr.deleteIn=Gr.removeIn=Cr.removeIn,Gr.merge=Cr.merge,Gr.mergeWith=Cr.mergeWith,Gr.mergeIn=Cr.mergeIn,Gr.mergeDeep=Cr.mergeDeep,Gr.mergeDeepWith=Cr.mergeDeepWith,Gr.mergeDeepIn=Cr.mergeDeepIn,Gr.setIn=Cr.setIn,Gr.update=Cr.update,Gr.updateIn=Cr.updateIn,Gr.withMutations=Cr.withMutations,Gr.asMutable=Cr.asMutable,Gr.asImmutable=Cr.asImmutable,t(Le,nt),Le.of=function(){return this(arguments)},Le.fromKeys=function(t){return this(r(t).keySeq())},Le.prototype.toString=function(){return this.__toString("Set {","}")},Le.prototype.has=function(t){return this._map.has(t)},Le.prototype.add=function(t){return Be(this,this._map.set(t,!0))},Le.prototype.remove=function(t){return Be(this,this._map.remove(t))},Le.prototype.clear=function(){return Be(this,this._map.clear())},Le.prototype.union=function(){var t=sr.call(arguments,0);return t=t.filter(function(t){return 0!==t.size}),0===t.length?this:0!==this.size||this.__ownerID||1!==t.length?this.withMutations(function(e){for(var r=0;t.length>r;r++)i(t[r]).forEach(function(t){return e.add(t)})}):this.constructor(t[0])},Le.prototype.intersect=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.every(function(t){return t.includes(e)})||r.remove(e)})})},Le.prototype.subtract=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.some(function(t){return t.includes(e)})&&r.remove(e)})})},Le.prototype.merge=function(){return this.union.apply(this,arguments)},Le.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return this.union.apply(this,e)}, -Le.prototype.sort=function(t){return Je(we(this,t))},Le.prototype.sortBy=function(t,e){return Je(we(this,e,t))},Le.prototype.wasAltered=function(){return this._map.wasAltered()},Le.prototype.__iterate=function(t,e){var r=this;return this._map.__iterate(function(e,n){return t(n,n,r)},e)},Le.prototype.__iterator=function(t,e){return this._map.map(function(t,e){return e}).__iterator(t,e)},Le.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t);return t?this.__make(e,t):(this.__ownerID=t,this._map=e,this)},Le.isSet=Te;var Zr="@@__IMMUTABLE_SET__@@",$r=Le.prototype;$r[Zr]=!0,$r[_r]=$r.remove,$r.mergeDeep=$r.merge,$r.mergeDeepWith=$r.mergeWith,$r.withMutations=Cr.withMutations,$r.asMutable=Cr.asMutable,$r.asImmutable=Cr.asImmutable,$r.__empty=Ce,$r.__make=We;var tn;t(Je,Le),Je.of=function(){return this(arguments)},Je.fromKeys=function(t){return this(r(t).keySeq())},Je.prototype.toString=function(){return this.__toString("OrderedSet {","}")},Je.isOrderedSet=Ne;var en=Je.prototype;en[cr]=!0,en.__empty=He,en.__make=Pe;var rn;t(Ve,rt),Ve.of=function(){return this(arguments)},Ve.prototype.toString=function(){return this.__toString("Stack [","]")},Ve.prototype.get=function(t,e){var r=this._head;for(t=l(this,t);r&&t--;)r=r.next;return r?r.value:e},Ve.prototype.peek=function(){return this._head&&this._head.value},Ve.prototype.push=function(){if(0===arguments.length)return this;for(var t=this.size+arguments.length,e=this._head,r=arguments.length-1;r>=0;r--)e={value:arguments[r],next:e};return this.__ownerID?(this.size=t,this._head=e,this.__hash=void 0,this.__altered=!0,this):Qe(t,e)},Ve.prototype.pushAll=function(t){if(t=n(t),0===t.size)return this;ft(t.size);var e=this.size,r=this._head;return t.reverse().forEach(function(t){e++,r={value:t,next:r}}),this.__ownerID?(this.size=e,this._head=r,this.__hash=void 0,this.__altered=!0,this):Qe(e,r)},Ve.prototype.pop=function(){return this.slice(1)},Ve.prototype.unshift=function(){return this.push.apply(this,arguments)},Ve.prototype.unshiftAll=function(t){ -return this.pushAll(t)},Ve.prototype.shift=function(){return this.pop.apply(this,arguments)},Ve.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Xe()},Ve.prototype.slice=function(t,e){if(d(t,e,this.size))return this;var r=m(t,this.size),n=g(e,this.size);if(n!==this.size)return rt.prototype.slice.call(this,t,e);for(var i=this.size-r,o=this._head;r--;)o=o.next;return this.__ownerID?(this.size=i,this._head=o,this.__hash=void 0,this.__altered=!0,this):Qe(i,o)},Ve.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Qe(this.size,this._head,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},Ve.prototype.__iterate=function(t,e){if(e)return this.reverse().__iterate(t);for(var r=0,n=this._head;n&&t(n.value,r++,this)!==!1;)n=n.next;return r},Ve.prototype.__iterator=function(t,e){if(e)return this.reverse().__iterator(t);var r=0,n=this._head;return new S(function(){if(n){var e=n.value;return n=n.next,z(t,r++,e)}return I()})},Ve.isStack=Ye;var nn="@@__IMMUTABLE_STACK__@@",on=Ve.prototype;on[nn]=!0,on.withMutations=Cr.withMutations,on.asMutable=Cr.asMutable,on.asImmutable=Cr.asImmutable,on.wasAltered=Cr.wasAltered;var un;e.Iterator=S,Fe(e,{toArray:function(){ft(this.size);var t=Array(this.size||0);return this.valueSeq().__iterate(function(e,r){t[r]=e}),t},toIndexedSeq:function(){return new ie(this)},toJS:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJS?t.toJS():t}).__toJS()},toJSON:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJSON?t.toJSON():t}).__toJS()},toKeyedSeq:function(){return new ne(this,!0)},toMap:function(){return ct(this.toKeyedSeq())},toObject:function(){ft(this.size);var t={};return this.__iterate(function(e,r){t[r]=e}),t},toOrderedMap:function(){return Zt(this.toKeyedSeq())},toOrderedSet:function(){return Je(u(this)?this.valueSeq():this)},toSet:function(){return Le(u(this)?this.valueSeq():this)},toSetSeq:function(){return new oe(this); -},toSeq:function(){return s(this)?this.toIndexedSeq():u(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Ve(u(this)?this.valueSeq():this)},toList:function(){return Bt(u(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(t,e){return 0===this.size?t+e:t+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+e},concat:function(){var t=sr.call(arguments,0);return be(this,ye(this,t))},includes:function(t){return this.some(function(e){return X(e,t)})},entries:function(){return this.__iterator(Sr)},every:function(t,e){ft(this.size);var r=!0;return this.__iterate(function(n,i,o){return t.call(e,n,i,o)?void 0:(r=!1,!1)}),r},filter:function(t,e){return be(this,fe(this,t,e,!0))},find:function(t,e,r){var n=this.findEntry(t,e);return n?n[1]:r},forEach:function(t,e){return ft(this.size),this.__iterate(e?t.bind(e):t)},join:function(t){ft(this.size),t=void 0!==t?""+t:",";var e="",r=!0;return this.__iterate(function(n){r?r=!1:e+=t,e+=null!==n&&void 0!==n?""+n:""}),e},keys:function(){return this.__iterator(gr)},map:function(t,e){return be(this,ae(this,t,e))},reduce:function(t,e,r){ft(this.size);var n,i;return arguments.length<2?i=!0:n=e,this.__iterate(function(e,o,u){i?(i=!1,n=e):n=t.call(r,n,e,o,u)}),n},reduceRight:function(t,e,r){var n=this.toKeyedSeq().reverse();return n.reduce.apply(n,arguments)},reverse:function(){return be(this,he(this,!0))},slice:function(t,e){return be(this,pe(this,t,e,!0))},some:function(t,e){return!this.every($e(t),e)},sort:function(t){return be(this,we(this,t))},values:function(){return this.__iterator(wr)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(t,e){return v(t?this.toSeq().filter(t,e):this)},countBy:function(t,e){return ce(this,t,e)},equals:function(t){return F(this,t)},entrySeq:function(){var t=this;if(t._cache)return new j(t._cache);var e=t.toSeq().map(Ze).toIndexedSeq();return e.fromEntrySeq=function(){return t.toSeq()},e},filterNot:function(t,e){ -return this.filter($e(t),e)},findEntry:function(t,e,r){var n=r;return this.__iterate(function(r,i,o){return t.call(e,r,i,o)?(n=[i,r],!1):void 0}),n},findKey:function(t,e){var r=this.findEntry(t,e);return r&&r[0]},findLast:function(t,e,r){return this.toKeyedSeq().reverse().find(t,e,r)},findLastEntry:function(t,e,r){return this.toKeyedSeq().reverse().findEntry(t,e,r)},findLastKey:function(t,e){return this.toKeyedSeq().reverse().findKey(t,e)},first:function(){return this.find(y)},flatMap:function(t,e){return be(this,me(this,t,e))},flatten:function(t){return be(this,de(this,t,!0))},fromEntrySeq:function(){return new ue(this)},get:function(t,e){return this.find(function(e,r){return X(r,t)},void 0,e)},getIn:function(t,e){for(var r,n=this,i=ke(t);!(r=i.next()).done;){var o=r.value;if(n=n&&n.get?n.get(o,yr):yr,n===yr)return e}return n},groupBy:function(t,e){return _e(this,t,e)},has:function(t){return this.get(t,yr)!==yr},hasIn:function(t){return this.getIn(t,yr)!==yr},isSubset:function(t){return t="function"==typeof t.includes?t:e(t),this.every(function(e){return t.includes(e)})},isSuperset:function(t){return t="function"==typeof t.isSubset?t:e(t),t.isSubset(this)},keyOf:function(t){return this.findKey(function(e){return X(e,t)})},keySeq:function(){return this.toSeq().map(Ge).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(t){return this.toKeyedSeq().reverse().keyOf(t)},max:function(t){return Se(this,t)},maxBy:function(t,e){return Se(this,e,t)},min:function(t){return Se(this,t?tr(t):nr)},minBy:function(t,e){return Se(this,e?tr(e):nr,t)},rest:function(){return this.slice(1)},skip:function(t){return this.slice(Math.max(0,t))},skipLast:function(t){return be(this,this.toSeq().reverse().skip(t).reverse())},skipWhile:function(t,e){return be(this,le(this,t,e,!0))},skipUntil:function(t,e){return this.skipWhile($e(t),e)},sortBy:function(t,e){return be(this,we(this,e,t))},take:function(t){return this.slice(0,Math.max(0,t))},takeLast:function(t){return be(this,this.toSeq().reverse().take(t).reverse()); -},takeWhile:function(t,e){return be(this,ve(this,t,e))},takeUntil:function(t,e){return this.takeWhile($e(t),e)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var sn=e.prototype;sn[ar]=!0,sn[br]=sn.values,sn.__toJS=sn.toArray,sn.__toStringMapper=er,sn.inspect=sn.toSource=function(){return""+this},sn.chain=sn.flatMap,sn.contains=sn.includes,Fe(r,{flip:function(){return be(this,se(this))},mapEntries:function(t,e){var r=this,n=0;return be(this,this.toSeq().map(function(i,o){return t.call(e,[o,i],n++,r)}).fromEntrySeq())},mapKeys:function(t,e){var r=this;return be(this,this.toSeq().flip().map(function(n,i){return t.call(e,n,i,r)}).flip())}});var an=r.prototype;an[hr]=!0,an[br]=sn.entries,an.__toJS=sn.toObject,an.__toStringMapper=function(t,e){return JSON.stringify(e)+": "+er(t)},Fe(n,{toKeyedSeq:function(){return new ne(this,!1)},filter:function(t,e){return be(this,fe(this,t,e,!1))},findIndex:function(t,e){var r=this.findEntry(t,e);return r?r[0]:-1},indexOf:function(t){var e=this.keyOf(t);return void 0===e?-1:e},lastIndexOf:function(t){var e=this.lastKeyOf(t);return void 0===e?-1:e},reverse:function(){return be(this,he(this,!1))},slice:function(t,e){return be(this,pe(this,t,e,!1))},splice:function(t,e){var r=arguments.length;if(e=Math.max(0|e,0),0===r||2===r&&!e)return this;t=m(t,0>t?this.count():this.size);var n=this.slice(0,t);return be(this,1===r?n:n.concat(p(arguments,2),this.slice(t+e)))},findLastIndex:function(t,e){var r=this.findLastEntry(t,e);return r?r[0]:-1},first:function(){return this.get(0)},flatten:function(t){return be(this,de(this,t,!1))},get:function(t,e){return t=l(this,t),0>t||this.size===1/0||void 0!==this.size&&t>this.size?e:this.find(function(e,r){return r===t},void 0,e)},has:function(t){return t=l(this,t),t>=0&&(void 0!==this.size?this.size===1/0||this.size>t:-1!==this.indexOf(t))},interpose:function(t){return be(this,ge(this,t))},interleave:function(){var t=[this].concat(p(arguments)),e=Ie(this.toSeq(),k.of,t),r=e.flatten(!0);return e.size&&(r.size=e.size*t.length), -be(this,r)},keySeq:function(){return $(0,this.size)},last:function(){return this.get(-1)},skipWhile:function(t,e){return be(this,le(this,t,e,!1))},zip:function(){var t=[this].concat(p(arguments));return be(this,Ie(this,rr,t))},zipWith:function(t){var e=p(arguments);return e[0]=this,be(this,Ie(this,t,e))}}),n.prototype[fr]=!0,n.prototype[cr]=!0,Fe(i,{get:function(t,e){return this.has(t)?t:e},includes:function(t){return this.has(t)},keySeq:function(){return this.valueSeq()}}),i.prototype.has=sn.includes,i.prototype.contains=i.prototype.includes,Fe(x,r.prototype),Fe(k,n.prototype),Fe(A,i.prototype),Fe(et,r.prototype),Fe(rt,n.prototype),Fe(nt,i.prototype);var hn={Iterable:e,Seq:O,Collection:tt,Map:ct,OrderedMap:Zt,List:Bt,Stack:Ve,Set:Le,OrderedSet:Je,Record:Ae,Range:$,Repeat:G,is:X,fromJS:H};return hn}); \ No newline at end of file diff --git a/third_party/immer/extra/js/lib/lodash.js b/third_party/immer/extra/js/lib/lodash.js deleted file mode 100644 index 22e73749bda6..000000000000 --- a/third_party/immer/extra/js/lib/lodash.js +++ /dev/null @@ -1,16607 +0,0 @@ -/** - * @license - * lodash - * Copyright jQuery Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '4.14.1'; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** Used to compose bitmasks for function metadata. */ - var BIND_FLAG = 1, - BIND_KEY_FLAG = 2, - CURRY_BOUND_FLAG = 4, - CURRY_FLAG = 8, - CURRY_RIGHT_FLAG = 16, - PARTIAL_FLAG = 32, - PARTIAL_RIGHT_FLAG = 64, - ARY_FLAG = 128, - REARG_FLAG = 256, - FLIP_FLAG = 512; - - /** Used to compose bitmasks for comparison styles. */ - var UNORDERED_COMPARE_FLAG = 1, - PARTIAL_COMPARE_FLAG = 2; - - /** Used as default options for `_.truncate`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2, - LAZY_WHILE_FLAG = 3; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991, - MAX_INTEGER = 1.7976931348623157e+308, - NAN = 0 / 0; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** Used to associate wrap methods with their bit flags. */ - var wrapFlags = [ - ['ary', ARY_FLAG], - ['bind', BIND_FLAG], - ['bindKey', BIND_KEY_FLAG], - ['curry', CURRY_FLAG], - ['curryRight', CURRY_RIGHT_FLAG], - ['flip', FLIP_FLAG], - ['partial', PARTIAL_FLAG], - ['partialRight', PARTIAL_RIGHT_FLAG], - ['rearg', REARG_FLAG] - ]; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - weakMapTag = '[object WeakMap]', - weakSetTag = '[object WeakSet]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, - reUnescapedHtml = /[&<>"'`]/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - reLeadingDot = /^\./, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, - reHasRegExpChar = RegExp(reRegExpChar.source); - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g, - reTrimStart = /^\s+/, - reTrimEnd = /\s+$/; - - /** Used to match wrap detail comments. */ - var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, - reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, - reSplitDetails = /,? & /; - - /** Used to match non-compound words composed of alphanumeric characters. */ - var reBasicWord = /[a-zA-Z0-9]+/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** - * Used to match - * [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0x/i; - - /** Used to detect bad signed hexadecimal string values. */ - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - - /** Used to detect binary string values. */ - var reIsBinary = /^0b[01]+$/i; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect octal string values. */ - var reIsOctal = /^0o[0-7]+$/i; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', - rsComboSymbolsRange = '\\u20d0-\\u20f0', - rsDingbatRange = '\\u2700-\\u27bf', - rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', - rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', - rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsPunctuationRange = '\\u2000-\\u206f', - rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', - rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', - rsVarRange = '\\ufe0e\\ufe0f', - rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; - - /** Used to compose unicode capture groups. */ - var rsApos = "['\u2019]", - rsAstral = '[' + rsAstralRange + ']', - rsBreak = '[' + rsBreakRange + ']', - rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', - rsDigits = '\\d+', - rsDingbat = '[' + rsDingbatRange + ']', - rsLower = '[' + rsLowerRange + ']', - rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsUpper = '[' + rsUpperRange + ']', - rsZWJ = '\\u200d'; - - /** Used to compose unicode regexes. */ - var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', - rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', - rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', - rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', - reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match apostrophes. */ - var reApos = RegExp(rsApos, 'g'); - - /** - * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and - * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). - */ - var reComboMark = RegExp(rsCombo, 'g'); - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** Used to match complex or compound words. */ - var reComplexWord = RegExp([ - rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', - rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', - rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr, - rsUpper + '+' + rsOptUpperContr, - rsDigits, - rsEmoji - ].join('|'), 'g'); - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); - - /** Used to detect strings that need a more robust regexp to match words. */ - var reHasComplexWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', - 'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', - 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' - ]; - - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = - cloneableTags[boolTag] = cloneableTags[dateTag] = - cloneableTags[float32Tag] = cloneableTags[float64Tag] = - cloneableTags[int8Tag] = cloneableTags[int16Tag] = - cloneableTags[int32Tag] = cloneableTags[mapTag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[setTag] = - cloneableTags[stringTag] = cloneableTags[symbolTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map latin-1 supplementary letters to basic latin letters. */ - var deburredLetters = { - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss' - }; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; - - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Built-in method references without a dependency on `root`. */ - var freeParseFloat = parseFloat, - freeParseInt = parseInt; - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - return freeProcess && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, - nodeIsDate = nodeUtil && nodeUtil.isDate, - nodeIsMap = nodeUtil && nodeUtil.isMap, - nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, - nodeIsSet = nodeUtil && nodeUtil.isSet, - nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /*--------------------------------------------------------------------------*/ - - /** - * Adds the key-value `pair` to `map`. - * - * @private - * @param {Object} map The map to modify. - * @param {Array} pair The key-value pair to add. - * @returns {Object} Returns `map`. - */ - function addMapEntry(map, pair) { - // Don't return `map.set` because it's not chainable in IE 11. - map.set(pair[0], pair[1]); - return map; - } - - /** - * Adds `value` to `set`. - * - * @private - * @param {Object} set The set to modify. - * @param {*} value The value to add. - * @returns {Object} Returns `set`. - */ - function addSetEntry(set, value) { - // Don't return `set.add` because it's not chainable in IE 11. - set.add(value); - return set; - } - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; - } - - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array ? array.length : 0; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array ? array.length : 0, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to search. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludes(array, value) { - var length = array ? array.length : 0; - return !!length && baseIndexOf(array, value, 0) > -1; - } - - /** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to search. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array ? array.length : 0, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array ? array.length : 0; - - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the last element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initAccum) { - var length = array ? array.length : 0; - if (initAccum && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to search. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return baseFindIndex(array, baseIsNaN, fromIndex); - } - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * This function is like `baseIndexOf` except that it accepts a comparator. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @param {Function} comparator The comparator invoked per element. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOfWith(array, value, fromIndex, comparator) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (comparator(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * The base implementation of `_.mean` and `_.meanBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the mean. - */ - function baseMean(array, iteratee) { - var length = array ? array.length : 0; - return length ? (baseSum(array, iteratee) / length) : NAN; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.propertyOf` without support for deep paths. - * - * @private - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyOf(object) { - return function(key) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * The base implementation of `_.sum` and `_.sumBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(array, iteratee) { - var result, - index = -1, - length = array.length; - - while (++index < length) { - var current = iteratee(array[index]); - if (current !== undefined) { - result = result === undefined ? current : (result + current); - } - } - return result; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** - * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array - * of key-value pairs for `object` corresponding to the property names of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the key-value pairs. - */ - function baseToPairs(object, props) { - return arrayMap(props, function(key) { - return [key, object[key]]; - }); - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); - } - - /** - * Checks if a cache value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Gets the number of `placeholder` occurrences in `array`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} placeholder The placeholder to search for. - * @returns {number} Returns the placeholder count. - */ - function countHolders(array, placeholder) { - var length = array.length, - result = 0; - - while (length--) { - if (array[length] === placeholder) { - result++; - } - } - return result; - } - - /** - * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - var deburrLetter = basePropertyOf(deburredLetters); - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - var escapeHtmlChar = basePropertyOf(htmlEscapes); - - /** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Checks if `value` is a host object in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a host object, else `false`. - */ - function isHostObject(value) { - // Many host objects are `Object` objects that can coerce to strings - // despite having improperly defined `toString` methods. - var result = false; - if (value != null && typeof value.toString != 'function') { - try { - result = !!(value + ''); - } catch (e) {} - } - return result; - } - - /** - * Converts `iterator` to an array. - * - * @private - * @param {Object} iterator The iterator to convert. - * @returns {Array} Returns the converted array. - */ - function iteratorToArray(iterator) { - var data, - result = []; - - while (!(data = iterator.next()).done) { - result.push(data.value); - } - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Creates a function that invokes `func` with its first argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value === placeholder || value === PLACEHOLDER) { - array[index] = PLACEHOLDER; - result[resIndex++] = index; - } - } - return result; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** - * Converts `set` to its value-value pairs. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the value-value pairs. - */ - function setToPairs(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = [value, value]; - }); - return result; - } - - /** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ - function stringSize(string) { - if (!(string && reHasComplexSymbol.test(string))) { - return string.length; - } - var result = reComplexSymbol.lastIndex = 0; - while (reComplexSymbol.test(string)) { - result++; - } - return result; - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return string.match(reComplexSymbol); - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - var unescapeHtmlChar = basePropertyOf(htmlUnescapes); - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the `context` object. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Util - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => true - * - * // Use `context` to stub `Date#getTime` use in `_.now`. - * var stubbed = _.runInContext({ - * 'Date': function() { - * return { 'getTime': stubGetTime }; - * } - * }); - * - * // Create a suped-up `defer` in Node.js. - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - function runInContext(context) { - context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; - - /** Built-in constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Math = context.Math, - RegExp = context.RegExp, - TypeError = context.TypeError; - - /** Used for built-in method references. */ - var arrayProto = context.Array.prototype, - objectProto = context.Object.prototype, - stringProto = context.String.prototype; - - /** Used to detect overreaching core-js shims. */ - var coreJsData = context['__core-js_shared__']; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** Used to resolve the decompiled source of functions. */ - var funcToString = context.Function.prototype.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString.call(Object); - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. - */ - var objectToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Built-in value references. */ - var Buffer = moduleExports ? context.Buffer : undefined, - Reflect = context.Reflect, - Symbol = context.Symbol, - Uint8Array = context.Uint8Array, - enumerate = Reflect ? Reflect.enumerate : undefined, - iteratorSymbol = Symbol ? Symbol.iterator : undefined, - objectCreate = context.Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; - - /** Built-in method references that are mockable. */ - var clearTimeout = function(id) { return context.clearTimeout.call(root, id); }, - setTimeout = function(func, wait) { return context.setTimeout.call(root, func, wait); }; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeFloor = Math.floor, - nativeGetPrototype = Object.getPrototypeOf, - nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeIsFinite = context.isFinite, - nativeJoin = arrayProto.join, - nativeKeys = Object.keys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random, - nativeReplace = stringProto.replace, - nativeReverse = arrayProto.reverse, - nativeSplit = stringProto.split; - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(context, 'DataView'), - Map = getNative(context, 'Map'), - Promise = getNative(context, 'Promise'), - Set = getNative(context, 'Set'), - WeakMap = getNative(context, 'WeakMap'), - nativeCreate = getNative(context.Object, 'create'); - - /* Used to set `toString` methods. */ - var defineProperty = (function() { - var func = getNative(context.Object, 'defineProperty'), - name = getNative.name; - - return (name && name.length > 2) ? func : undefined; - }()); - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ - var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array of at least `200` elements - * and any iteratees accept only one argument. The heuristic for whether a - * section qualifies for shortcut fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The function whose prototype chain sequence wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. - */ - function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; - } - - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. - * - * @static - * @memberOf _ - * @type {Object} - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type {string} - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type {Object} - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type {Function} - */ - '_': lodash - } - }; - - // Ensure wrappers are instances of `baseLodash`. - lodash.prototype = baseLodash.prototype; - lodash.prototype.constructor = lodash; - - LodashWrapper.prototype = baseCreate(baseLodash.prototype); - LodashWrapper.prototype.constructor = LodashWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = copyArray(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = copyArray(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = copyArray(this.__views__); - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || arrLength < LARGE_ARRAY_SIZE || - (arrLength == length && takeCount == length)) { - return baseWrapperValue(array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; - } - - // Ensure `LazyWrapper` is an instance of `baseLodash`. - LazyWrapper.prototype = baseCreate(baseLodash.prototype); - LazyWrapper.prototype.constructor = LazyWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; - } - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; - } - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); - } - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - } - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - return getMapData(this, key)['delete'](key); - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values ? values.length : 0; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - this.__data__ = new ListCache(entries); - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - return this.__data__['delete'](key); - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var cache = this.__data__; - if (cache instanceof ListCache) { - var pairs = cache.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - return this; - } - cache = this.__data__ = new MapCache(pairs); - } - cache.set(key, value); - return this; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /*------------------------------------------------------------------------*/ - - /** - * Used by `_.defaults` to customize its `_.assignIn` use. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to assign. - * @param {Object} object The parent object of `objValue`. - * @returns {*} Returns the value to assign. - */ - function assignInDefaults(objValue, srcValue, key, object) { - if (objValue === undefined || - (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { - return srcValue; - } - return objValue; - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (typeof key == 'number' && value === undefined && !(key in object))) { - object[key] = value; - } - } - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - object[key] = value; - } - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to search. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); - } - - /** - * The base implementation of `_.at` without support for individual paths. - * - * @private - * @param {Object} object The object to iterate over. - * @param {string[]} paths The property paths of elements to pick. - * @returns {Array} Returns the picked elements. - */ - function baseAt(object, paths) { - var index = -1, - isNil = object == null, - length = paths.length, - result = Array(length); - - while (++index < length) { - result[index] = isNil ? undefined : get(object, paths[index]); - } - return result; - } - - /** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ - function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } - } - return number; - } - - /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {boolean} [isFull] Specify a clone including symbols. - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, isFull, customizer, key, object, stack) { - var result; - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - if (isHostObject(value)) { - return object ? value : {}; - } - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, baseClone, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (!isArr) { - var props = isFull ? getAllKeys(value) : keys(value); - } - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); - }); - return result; - } - - /** - * The base implementation of `_.conforms` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new spec function. - */ - function baseConforms(source) { - var props = keys(source); - return function(object) { - return baseConformsTo(object, source, props); - }; - } - - /** - * The base implementation of `_.conformsTo` which accepts `props` to check. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - */ - function baseConformsTo(object, source, props) { - var length = props.length; - if (object == null) { - return !length; - } - var index = length; - while (index--) { - var key = props[index], - predicate = source[key], - value = object[key]; - - if ((value === undefined && - !(key in Object(object))) || !predicate(value)) { - return false; - } - } - return true; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(proto) { - return isObject(proto) ? objectCreate(proto) : {}; - } - - /** - * The base implementation of `_.delay` and `_.defer` which accepts `args` - * to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Array} args The arguments to provide to `func`. - * @returns {number} Returns the timer id. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEachRight = createBaseEach(baseForOwnRight, true); - - /** - * The base implementation of `_.every` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * The base implementation of methods like `_.max` and `_.min` which accepts a - * `comparator` to determine the extremum value. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The iteratee invoked per iteration. - * @param {Function} comparator The comparator used to compare values. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(array, iteratee, comparator) { - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index], - current = iteratee(value); - - if (current != null && (computed === undefined - ? (current === current && !isSymbol(current)) - : comparator(current, computed) - )) { - var computed = current, - result = value; - } - } - return result; - } - - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = toInteger(start); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : toInteger(end); - if (end < 0) { - end += length; - } - end = start > end ? 0 : toLength(end); - while (start < end) { - array[start++] = value; - } - return array; - } - - /** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return object && baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from `props`. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the function names. - */ - function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); - }); - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * The base implementation of `getTag`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - return objectToString.call(value); - } - - /** - * The base implementation of `_.gt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - */ - function baseGt(value, other) { - return value > other; - } - - /** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHas(object, key) { - // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, - // that are composed entirely of index properties, return `false` for - // `hasOwnProperty` checks of them. - return object != null && - (hasOwnProperty.call(object, key) || - (typeof object == 'object' && key in object && getPrototype(object) === null)); - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * The base implementation of `_.inRange` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to check. - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - */ - function baseInRange(number, start, end) { - return number >= nativeMin(start, end) && number < nativeMax(start, end); - } - - /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. - */ - function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; - - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; - } - array = arrays[0]; - - var index = -1, - seen = caches[0]; - - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.invert` and `_.invertBy` which inverts - * `object` with values transformed by `iteratee` and set by `setter`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform values. - * @param {Object} accumulator The initial inverted object. - * @returns {Function} Returns `accumulator`. - */ - function baseInverter(object, setter, iteratee, accumulator) { - baseForOwn(object, function(value, key, object) { - setter(accumulator, iteratee(value), key, object); - }); - return accumulator; - } - - /** - * The base implementation of `_.invoke` without support for individual - * method arguments. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function baseInvoke(object, path, args) { - if (!isKey(path, object)) { - path = castPath(path); - object = parent(object, path); - path = last(path); - } - var func = object == null ? object : object[toKey(path)]; - return func == null ? undefined : apply(func, object, args); - } - - /** - * The base implementation of `_.isArrayBuffer` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - */ - function baseIsArrayBuffer(value) { - return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; - } - - /** - * The base implementation of `_.isDate` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - */ - function baseIsDate(value) { - return isObjectLike(value) && objectToString.call(value) == dateTag; - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @param {boolean} [bitmask] The bitmask of comparison flags. - * The bitmask may be composed of the following flags: - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, customizer, bitmask, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparisons. - * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = getTag(object); - objTag = objTag == argsTag ? objectTag : objTag; - } - if (!othIsArr) { - othTag = getTag(other); - othTag = othTag == argsTag ? objectTag : othTag; - } - var objIsObj = objTag == objectTag && !isHostObject(object), - othIsObj = othTag == objectTag && !isHostObject(other), - isSameTag = objTag == othTag; - - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) - : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); - } - if (!(bitmask & PARTIAL_COMPARE_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, equalFunc, customizer, bitmask, stack); - } - - /** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ - function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; - } - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * The base implementation of `_.isRegExp` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - */ - function baseIsRegExp(value) { - return isObject(value) && objectToString.call(value) == regexpTag; - } - - /** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ - function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; - } - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * The base implementation of `_.keys` which doesn't skip the constructor - * property of prototypes or treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - var baseKeys = overArg(nativeKeys, Object); - - /** - * The base implementation of `_.keysIn` which doesn't skip the constructor - * property of prototypes or treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - object = object == null ? object : Object(object); - - var result = []; - for (var key in object) { - result.push(key); - } - return result; - } - - // Fallback for IE < 9 with es6-shim. - if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { - baseKeysIn = function(object) { - return iteratorToArray(enumerate(object)); - }; - } - - /** - * The base implementation of `_.lt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - */ - function baseLt(value, other) { - return value < other; - } - - /** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); - }; - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - if (!(isArray(source) || isTypedArray(source))) { - var props = keysIn(source); - } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(object[key], srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = object[key], - srcValue = source[key], - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - newValue = srcValue; - if (isArray(srcValue) || isTypedArray(srcValue)) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else { - isCommon = false; - newValue = baseClone(srcValue, true); - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { - isCommon = false; - newValue = baseClone(srcValue, true); - } - else { - newValue = objValue; - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.nth` which doesn't coerce arguments. - * - * @private - * @param {Array} array The array to query. - * @param {number} n The index of the element to return. - * @returns {*} Returns the nth element of `array`. - */ - function baseNth(array, n) { - var length = array.length; - if (!length) { - return; - } - n += n < 0 ? length : 0; - return isIndex(n, length) ? array[n] : undefined; - } - - /** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseOrderBy(collection, iteratees, orders) { - var index = -1; - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); - - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } - - /** - * The base implementation of `_.pick` without support for individual - * property identifiers. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property identifiers to pick. - * @returns {Object} Returns the new object. - */ - function basePick(object, props) { - object = Object(object); - return basePickBy(object, props, function(value, key) { - return key in object; - }); - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property identifiers to pick from. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, props, predicate) { - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; - - if (predicate(value, key)) { - result[key] = value; - } - } - return result; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * The base implementation of `_.pullAllBy` without support for iteratee - * shorthands. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - */ - function basePullAll(array, values, iteratee, comparator) { - var indexOf = comparator ? baseIndexOfWith : baseIndexOf, - index = -1, - length = values.length, - seen = array; - - if (array === values) { - values = copyArray(values); - } - if (iteratee) { - seen = arrayMap(array, baseUnary(iteratee)); - } - while (++index < length) { - var fromIndex = 0, - value = values[index], - computed = iteratee ? iteratee(value) : value; - - while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { - if (seen !== array) { - splice.call(seen, fromIndex, 1); - } - splice.call(array, fromIndex, 1); - } - } - return array; - } - - /** - * The base implementation of `_.pullAt` without support for individual - * indexes or capturing the removed elements. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. - */ - function basePullAt(array, indexes) { - var length = array ? indexes.length : 0, - lastIndex = length - 1; - - while (length--) { - var index = indexes[length]; - if (length == lastIndex || index !== previous) { - var previous = index; - if (isIndex(index)) { - splice.call(array, index, 1); - } - else if (!isKey(index, array)) { - var path = castPath(index), - object = parent(array, path); - - if (object != null) { - delete object[toKey(last(path))]; - } - } - else { - delete array[toKey(index)]; - } - } - } - return array; - } - - /** - * The base implementation of `_.random` without support for returning - * floating-point numbers. - * - * @private - * @param {number} lower The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the random number. - */ - function baseRandom(lower, upper) { - return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); - } - - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } - - /** - * The base implementation of `_.repeat` which doesn't coerce arguments. - * - * @private - * @param {string} string The string to repeat. - * @param {number} n The number of times to repeat the string. - * @returns {string} Returns the repeated string. - */ - function baseRepeat(string, n) { - var result = ''; - if (!string || n < 1 || n > MAX_SAFE_INTEGER) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - if (n) { - string += string; - } - } while (n); - - return result; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = array; - return apply(func, this, otherArgs); - }; - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]); - if (isObject(nested)) { - var newValue = value; - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = objValue == null - ? (isIndex(path[index + 1]) ? [] : {}) - : objValue; - } - } - assignValue(nested, key, newValue); - } - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `setData` without support for hot loop detection. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which - * performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (computed !== null && !isSymbol(computed) && - (retHighest ? (computed <= value) : (computed < value))) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return baseSortedIndexBy(array, value, identity, retHighest); - } - - /** - * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` - * which invokes `iteratee` for `value` and each element of `array` to compute - * their sort ranking. The iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The iteratee invoked per element. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsNull = value === null, - valIsSymbol = isSymbol(value), - valIsUndefined = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - othIsDefined = computed !== undefined, - othIsNull = computed === null, - othIsReflexive = computed === computed, - othIsSymbol = isSymbol(computed); - - if (valIsNaN) { - var setLow = retHighest || othIsReflexive; - } else if (valIsUndefined) { - setLow = othIsReflexive && (retHighest || othIsDefined); - } else if (valIsNull) { - setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); - } else if (valIsSymbol) { - setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); - } else if (othIsNull || othIsSymbol) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - /** - * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseSortedUniq(array, iteratee) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - if (!index || !eq(computed, seen)) { - var seen = computed; - result[resIndex++] = value === 0 ? 0 : value; - } - } - return result; - } - - /** - * The base implementation of `_.toNumber` which doesn't ensure correct - * conversions of binary, hexadecimal, or octal string values. - * - * @private - * @param {*} value The value to process. - * @returns {number} Returns the number. - */ - function baseToNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - return +value; - } - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ - function baseUnset(object, path) { - path = isKey(path, object) ? [path] : castPath(path); - object = parent(object, path); - - var key = toKey(last(path)); - return !(object != null && baseHas(object, key)) || delete object[key]; - } - - /** - * The base implementation of `_.update`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to update. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseUpdate(object, path, updater, customizer) { - return baseSet(object, path, updater(baseGet(object, path)), customizer); - } - - /** - * The base implementation of methods like `_.dropWhile` and `_.takeWhile` - * without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. - */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length) && - predicate(array[index], index, array)) {} - - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to perform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - return arrayReduce(actions, function(result, action) { - return action.func.apply(action.thisArg, arrayPush([result], action.args)); - }, result); - } - - /** - * The base implementation of methods like `_.xor`, without support for - * iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of values. - */ - function baseXor(arrays, iteratee, comparator) { - var index = -1, - length = arrays.length; - - while (++index < length) { - var result = result - ? arrayPush( - baseDifference(result, arrays[index], iteratee, comparator), - baseDifference(arrays[index], result, iteratee, comparator) - ) - : arrays[index]; - } - return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; - } - - /** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ - function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); - } - return result; - } - - /** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ - function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ - function castFunction(value) { - return typeof value == 'function' ? value : identity; - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value) { - return isArray(value) ? value : stringToPath(value); - } - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var result = new buffer.constructor(buffer.length); - buffer.copy(result); - return result; - } - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ - function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); - } - - /** - * Creates a clone of `map`. - * - * @private - * @param {Object} map The map to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned map. - */ - function cloneMap(map, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); - return arrayReduce(array, addMapEntry, new map.constructor); - } - - /** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ - function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; - } - - /** - * Creates a clone of `set`. - * - * @private - * @param {Object} set The set to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned set. - */ - function cloneSet(set, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); - return arrayReduce(array, addSetEntry, new set.constructor); - } - - /** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ - function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); - - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); - - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } - } - return 0; - } - - /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersLength = holders.length, - leftIndex = -1, - leftLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(leftLength + rangeLength), - isUncurried = !isCurried; - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - } - while (rangeLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersIndex = -1, - holdersLength = holders.length, - rightIndex = -1, - rightLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(rangeLength + rightLength), - isUncurried = !isCurried; - - while (++argsIndex < rangeLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - } - return result; - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - assignValue(object, key, newValue === undefined ? source[key] : newValue); - } - return object; - } - - /** - * Copies own symbol properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); - } - - /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; - - return func(collection, setter, getIteratee(iteratee, 2), accumulator); - }; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` to invoke it with the optional `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createBind(func, bitmask, thisArg) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, arguments); - } - return wrapper; - } - - /** - * Creates a function like `_.lowerFirst`. - * - * @private - * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new case function. - */ - function createCaseFirst(methodName) { - return function(string) { - string = toString(string); - - var strSymbols = reHasComplexSymbol.test(string) - ? stringToArray(string) - : undefined; - - var chr = strSymbols - ? strSymbols[0] - : string.charAt(0); - - var trailing = strSymbols - ? castSlice(strSymbols, 1).join('') - : string.slice(1); - - return chr[methodName]() + trailing; - }; - } - - /** - * Creates a function like `_.camelCase`. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); - }; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtor(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. See - // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a function that wraps `func` to enable currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {number} arity The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createCurry(func, bitmask, arity) { - var Ctor = createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length, - placeholder = getHolder(wrapper); - - while (index--) { - args[index] = arguments[index]; - } - var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) - ? [] - : replaceHolders(args, placeholder); - - length -= holders.length; - if (length < arity) { - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, undefined, - args, holders, undefined, undefined, arity - length); - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return apply(fn, this, args); - } - return wrapper; - } - - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ - function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = getIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; - } - - /** - * Creates a `_.flow` or `_.flowRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return baseRest(function(funcs) { - funcs = baseFlatten(funcs, 1); - - var length = funcs.length, - index = length, - prereq = LodashWrapper.prototype.thru; - - if (fromRight) { - funcs.reverse(); - } - while (index--) { - var func = funcs[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (prereq && !wrapper && getFuncName(func) == 'wrapper') { - var wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? index : length; - while (++index < length) { - func = funcs[index]; - - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; - - if (data && isLaziable(data[0]) && - data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && - !data[4].length && data[9] == 1 - ) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) - ? wrapper[funcName]() - : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; - - if (wrapper && args.length == 1 && - isArray(value) && value.length >= LARGE_ARRAY_SIZE) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }); - } - - /** - * Creates a function that wraps `func` to invoke it with optional `this` - * binding of `thisArg`, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided - * to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & ARY_FLAG, - isBind = bitmask & BIND_FLAG, - isBindKey = bitmask & BIND_KEY_FLAG, - isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), - isFlip = bitmask & FLIP_FLAG, - Ctor = isBindKey ? undefined : createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length; - - while (index--) { - args[index] = arguments[index]; - } - if (isCurried) { - var placeholder = getHolder(wrapper), - holdersCount = countHolders(args, placeholder); - } - if (partials) { - args = composeArgs(args, partials, holders, isCurried); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight, isCurried); - } - length -= holdersCount; - if (isCurried && length < arity) { - var newHolders = replaceHolders(args, placeholder); - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, thisArg, - args, newHolders, argPos, ary, arity - length - ); - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - length = args.length; - if (argPos) { - args = reorder(args, argPos); - } else if (isFlip && length > 1) { - args.reverse(); - } - if (isAry && ary < length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtor(fn); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates a function like `_.invertBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} toIteratee The function to resolve iteratees. - * @returns {Function} Returns the new inverter function. - */ - function createInverter(setter, toIteratee) { - return function(object, iteratee) { - return baseInverter(object, setter, toIteratee(iteratee), {}); - }; - } - - /** - * Creates a function that performs a mathematical operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @param {number} [defaultValue] The value used for `undefined` arguments. - * @returns {Function} Returns the new mathematical operation function. - */ - function createMathOperation(operator, defaultValue) { - return function(value, other) { - var result; - if (value === undefined && other === undefined) { - return defaultValue; - } - if (value !== undefined) { - result = value; - } - if (other !== undefined) { - if (result === undefined) { - return other; - } - if (typeof value == 'string' || typeof other == 'string') { - value = baseToString(value); - other = baseToString(other); - } else { - value = baseToNumber(value); - other = baseToNumber(other); - } - result = operator(value, other); - } - return result; - }; - } - - /** - * Creates a function like `_.over`. - * - * @private - * @param {Function} arrayFunc The function to iterate over iteratees. - * @returns {Function} Returns the new over function. - */ - function createOver(arrayFunc) { - return baseRest(function(iteratees) { - iteratees = (iteratees.length == 1 && isArray(iteratees[0])) - ? arrayMap(iteratees[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(iteratees, 1), baseUnary(getIteratee())); - - return baseRest(function(args) { - var thisArg = this; - return arrayFunc(iteratees, function(iteratee) { - return apply(iteratee, thisArg, args); - }); - }); - }); - } - - /** - * Creates the padding for `string` based on `length`. The `chars` string - * is truncated if the number of characters exceeds `length`. - * - * @private - * @param {number} length The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padding for `string`. - */ - function createPadding(length, chars) { - chars = chars === undefined ? ' ' : baseToString(chars); - - var charsLength = chars.length; - if (charsLength < 2) { - return charsLength ? baseRepeat(chars, length) : chars; - } - var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); - return reHasComplexSymbol.test(chars) - ? castSlice(stringToArray(result), 0, length).join('') - : result.slice(0, length); - } - - /** - * Creates a function that wraps `func` to invoke it with the `this` binding - * of `thisArg` and `partials` prepended to the arguments it receives. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to - * the new function. - * @returns {Function} Returns the new wrapped function. - */ - function createPartial(func, bitmask, thisArg, partials) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength), - fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return apply(fn, isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - function createRange(fromRight) { - return function(start, end, step) { - if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { - end = step = undefined; - } - // Ensure the sign of `-0` is preserved. - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); - return baseRange(start, end, step, fromRight); - }; - } - - /** - * Creates a function that performs a relational operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @returns {Function} Returns the new relational operation function. - */ - function createRelationalOperation(operator) { - return function(value, other) { - if (!(typeof value == 'string' && typeof other == 'string')) { - value = toNumber(value); - other = toNumber(other); - } - return operator(value, other); - }; - } - - /** - * Creates a function that wraps `func` to continue currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {Function} wrapFunc The function to create the `func` wrapper. - * @param {*} placeholder The placeholder value. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { - var isCurry = bitmask & CURRY_FLAG, - newHolders = isCurry ? holders : undefined, - newHoldersRight = isCurry ? undefined : holders, - newPartials = isCurry ? partials : undefined, - newPartialsRight = isCurry ? undefined : partials; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!(bitmask & CURRY_BOUND_FLAG)) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [ - func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, - newHoldersRight, argPos, ary, arity - ]; - - var result = wrapFunc.apply(undefined, newData); - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return setWrapToString(result, func, bitmask); - } - - /** - * Creates a function like `_.round`. - * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. - */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - number = toNumber(number); - precision = nativeMin(toInteger(precision), 292); - if (precision) { - // Shift with exponential notation to avoid floating-point issues. - // See [MDN](https://mdn.io/round#Examples) for more details. - var pair = (toString(number) + 'e').split('e'), - value = func(pair[0] + 'e' + (+pair[1] + precision)); - - pair = (toString(value) + 'e').split('e'); - return +(pair[0] + 'e' + (+pair[1] - precision)); - } - return func(number); - }; - } - - /** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ - var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); - }; - - /** - * Creates a `_.toPairs` or `_.toPairsIn` function. - * - * @private - * @param {Function} keysFunc The function to get the keys of a given object. - * @returns {Function} Returns the new pairs function. - */ - function createToPairs(keysFunc) { - return function(object) { - var tag = getTag(object); - if (tag == mapTag) { - return mapToArray(object); - } - if (tag == setTag) { - return setToPairs(object); - } - return baseToPairs(object, keysFunc(object)); - }; - } - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * 512 - `_.flip` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); - arity = arity === undefined ? arity : toInteger(arity); - length -= holders ? holders.length : 0; - - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func); - - var newData = [ - func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, - argPos, ary, arity - ]; - - if (data) { - mergeData(newData, data); - } - func = newData[0]; - bitmask = newData[1]; - thisArg = newData[2]; - partials = newData[3]; - holders = newData[4]; - arity = newData[9] = newData[9] == null - ? (isBindKey ? 0 : func.length) - : nativeMax(newData[9] - length, 0); - - if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { - bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); - } - if (!bitmask || bitmask == BIND_FLAG) { - var result = createBind(func, bitmask, thisArg); - } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { - result = createCurry(func, bitmask, arity); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { - result = createPartial(func, bitmask, thisArg, partials); - } else { - result = createHybrid.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setWrapToString(setter(result, newData), func, bitmask); - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { - var isPartial = bitmask & PARTIAL_COMPARE_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!seen.has(othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { - return seen.add(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, customizer, bitmask, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & PARTIAL_COMPARE_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= UNORDERED_COMPARE_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { - var isPartial = bitmask & PARTIAL_COMPARE_FLAG, - objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : baseHas(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } - - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getHolder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; - } - - /** - * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, - * this function returns the custom method, otherwise it returns `baseIteratee`. - * If arguments are provided, the chosen function is invoked with them and - * its result is returned. - * - * @private - * @param {*} [value] The value to convert to an iteratee. - * @param {number} [arity] The arity of the created iteratee. - * @returns {Function} Returns the chosen function or its result. - */ - function getIteratee() { - var result = lodash.iteratee || iteratee; - result = result === iteratee ? baseIteratee : result; - return arguments.length ? result(arguments[0], arguments[1]) : result; - } - - /** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a - * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects - * Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ - var getLength = baseProperty('length'); - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /** - * Gets the `[[Prototype]]` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {null|Object} Returns the `[[Prototype]]`. - */ - var getPrototype = overArg(nativeGetPrototype, Object); - - /** - * Creates an array of the own enumerable symbol properties of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; - - /** - * Creates an array of the own and inherited enumerable symbol properties - * of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11, - // for data views in Edge, and promises in Node.js. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = objectToString.call(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : undefined; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Extracts wrapper details from the `source` body comment. - * - * @private - * @param {string} source The source to inspect. - * @returns {Array} Returns the wrapper details. - */ - function getWrapDetails(source) { - var match = source.match(reWrapDetails); - return match ? match[1].split(reSplitDetails) : []; - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = isKey(path, object) ? [path] : castPath(path); - - var result, - index = -1, - length = path.length; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result) { - return result; - } - var length = object ? object.length : 0; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isString(object) || isArguments(object)); - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, cloneFunc, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case dataViewTag: - return cloneDataView(object, isDeep); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); - - case mapTag: - return cloneMap(object, isDeep, cloneFunc); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - return cloneRegExp(object); - - case setTag: - return cloneSet(object, isDeep, cloneFunc); - - case symbolTag: - return cloneSymbol(object); - } - } - - /** - * Creates an array of index keys for `object` values of arrays, - * `arguments` objects, and strings, otherwise `null` is returned. - * - * @private - * @param {Object} object The object to query. - * @returns {Array|null} Returns index keys, else `null`. - */ - function indexKeys(object) { - var length = object ? object.length : undefined; - if (isLength(length) && - (isArray(object) || isString(object) || isArguments(object))) { - return baseTimes(length, String); - } - return null; - } - - /** - * Inserts wrapper `details` in a comment at the top of the `source` body. - * - * @private - * @param {string} source The source to modify. - * @returns {Array} details The details to insert. - * @returns {string} Returns the modified source. - */ - function insertWrapDetails(source, details) { - var length = details.length, - lastIndex = length - 1; - - details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; - details = details.join(length > 2 ? ', ' : ' '); - return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); - } - - /** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ - function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; - } - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** - * Checks if `func` is capable of being masked. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `func` is maskable, else `false`. - */ - var isMaskable = coreJsData ? isFunction : stubFalse; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers used to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and - * `_.rearg` modify function arguments, making the order in which they are - * executed important, preventing the merging of metadata. However, we make - * an exception for a safe combined case where curried functions have `_.ary` - * and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); - - var isCombo = - ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || - ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || - ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : value; - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = value; - } - // Use source `ary` if it's smaller. - if (srcBitmask & ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ - function mergeDefaults(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, mergeDefaults, stack); - stack['delete'](srcValue); - } - return objValue; - } - - /** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ - function parent(object, path) { - return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = copyArray(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity - * function to avoid garbage collection pauses in V8. See - * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = (function() { - var count = 0, - lastCalled = 0; - - return function(key, value) { - var stamp = now(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return key; - } - } else { - count = 0; - } - return baseSetData(key, value); - }; - }()); - - /** - * Sets the `toString` method of `wrapper` to mimic the source of `reference` - * with wrapper details in a comment at the top of the source body. - * - * @private - * @param {Function} wrapper The function to modify. - * @param {Function} reference The reference function. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Function} Returns `wrapper`. - */ - var setWrapToString = !defineProperty ? identity : function(wrapper, reference, bitmask) { - var source = (reference + ''); - return defineProperty(wrapper, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))) - }); - }; - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoize(function(string) { - string = toString(string); - - var result = []; - if (reLeadingDot.test(string)) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to process. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Updates wrapper `details` based on `bitmask` flags. - * - * @private - * @returns {Array} details The details to modify. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Array} Returns `details`. - */ - function updateWrapDetails(details, bitmask) { - arrayEach(wrapFlags, function(pair) { - var value = '_.' + pair[0]; - if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { - details.push(value); - } - }); - return details.sort(); - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `array` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array of chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array ? array.length : 0; - if (!length || size < 1) { - return []; - } - var index = 0, - resIndex = 0, - result = Array(nativeCeil(length / size)); - - while (index < length) { - result[resIndex++] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - function concat() { - var length = arguments.length, - args = Array(length ? length - 1 : 0), - array = arguments[0], - index = length; - - while (index--) { - args[index - 1] = arguments[index]; - } - return length - ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)) - : []; - } - - /** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. The order of result values is determined by the - * order they occur in the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ - var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `iteratee` which - * is invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. Result values are chosen from the first array. - * The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.pullAllBy`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2] - * - * // The `_.property` iteratee shorthand. - * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var differenceBy = baseRest(function(array, values) { - var iteratee = last(values); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `comparator` - * which is invoked to compare elements of `array` to `values`. Result values - * are chosen from the first array. The comparator is invoked with two arguments: - * (arrVal, othVal). - * - * **Note:** Unlike `_.pullAllWith`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * - * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); - * // => [{ 'x': 2, 'y': 1 }] - */ - var differenceWith = baseRest(function(array, values) { - var comparator = last(values); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) - : []; - }); - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.dropRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney'] - * - * // The `_.matches` iteratee shorthand. - * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropRightWhile(users, ['active', false]); - * // => objects for ['barney'] - * - * // The `_.property` iteratee shorthand. - * _.dropRightWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true, true) - : []; - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.dropWhile(users, function(o) { return !o.active; }); - * // => objects for ['pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.dropWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropWhile(users, ['active', false]); - * // => objects for ['pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.dropWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true) - : []; - } - - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Array - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] - * - * _.fill(Array(3), 2); - * // => [2, 2, 2] - * - * _.fill([4, 6, 8, 10], '*', 1, 3); - * // => [4, '*', '*', 10] - */ - function fill(array, value, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ - function findIndex(array, predicate, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, getIteratee(predicate, 3), index); - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); - * // => 2 - * - * // The `_.matches` iteratee shorthand. - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastIndex(users, ['active', false]); - * // => 2 - * - * // The `_.property` iteratee shorthand. - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length - 1; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = fromIndex < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1); - } - return baseFindIndex(array, getIteratee(predicate, 3), index, true); - } - - /** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ - function flatten(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, 1) : []; - } - - /** - * Recursively flattens `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, [3, [4]], 5]]); - * // => [1, 2, 3, 4, 5] - */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, INFINITY) : []; - } - - /** - * Recursively flatten `array` up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Array - * @param {Array} array The array to flatten. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * var array = [1, [2, [3, [4]], 5]]; - * - * _.flattenDepth(array, 1); - * // => [1, 2, [3, [4]], 5] - * - * _.flattenDepth(array, 2); - * // => [1, 2, 3, [4], 5] - */ - function flattenDepth(array, depth) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(array, depth); - } - - /** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } - */ - function fromPairs(pairs) { - var index = -1, - length = pairs ? pairs.length : 0, - result = {}; - - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; - } - return result; - } - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ - function head(array) { - return (array && array.length) ? array[0] : undefined; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it's used as the - * offset from the end of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // Search from the `fromIndex`. - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - */ - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseIndexOf(array, value, index); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - return dropRight(array, 1); - } - - /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. The order of result values is determined by the - * order they occur in the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersection([2, 1], [2, 3]); - * // => [2] - */ - var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `iteratee` - * which is invoked for each element of each `arrays` to generate the criterion - * by which they're compared. Result values are chosen from the first array. - * The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [2.1] - * - * // The `_.property` iteratee shorthand. - * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }] - */ - var intersectionBy = baseRest(function(arrays) { - var iteratee = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - if (iteratee === last(mapped)) { - iteratee = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `comparator` - * which is invoked to compare elements of `arrays`. Result values are chosen - * from the first array. The comparator is invoked with two arguments: - * (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.intersectionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }] - */ - var intersectionWith = baseRest(function(arrays) { - var comparator = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - if (comparator === last(mapped)) { - comparator = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, undefined, comparator) - : []; - }); - - /** - * Converts all elements in `array` into a string separated by `separator`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to convert. - * @param {string} [separator=','] The element separator. - * @returns {string} Returns the joined string. - * @example - * - * _.join(['a', 'b', 'c'], '~'); - * // => 'a~b~c' - */ - function join(array, separator) { - return array ? nativeJoin.call(array, separator) : ''; - } - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; - } - - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 - * - * // Search from the `fromIndex`. - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = ( - index < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1) - ) + 1; - } - if (value !== value) { - return baseFindIndex(array, baseIsNaN, index - 1, true); - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Gets the element at index `n` of `array`. If `n` is negative, the nth - * element from the end is returned. - * - * @static - * @memberOf _ - * @since 4.11.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=0] The index of the element to return. - * @returns {*} Returns the nth element of `array`. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * - * _.nth(array, 1); - * // => 'b' - * - * _.nth(array, -2); - * // => 'c'; - */ - function nth(array, n) { - return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; - } - - /** - * Removes all given values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` - * to remove elements from an array by predicate. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pull(array, 'a', 'c'); - * console.log(array); - * // => ['b', 'b'] - */ - var pull = baseRest(pullAll); - - /** - * This method is like `_.pull` except that it accepts an array of values to remove. - * - * **Note:** Unlike `_.difference`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pullAll(array, ['a', 'c']); - * console.log(array); - * // => ['b', 'b'] - */ - function pullAll(array, values) { - return (array && array.length && values && values.length) - ? basePullAll(array, values) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `iteratee` which is - * invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.differenceBy`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; - * - * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); - * console.log(array); - * // => [{ 'x': 2 }] - */ - function pullAllBy(array, values, iteratee) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, getIteratee(iteratee, 2)) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `comparator` which - * is invoked to compare elements of `array` to `values`. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.differenceWith`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; - * - * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); - * console.log(array); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] - */ - function pullAllWith(array, values, comparator) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, undefined, comparator) - : array; - } - - /** - * Removes elements from `array` corresponding to `indexes` and returns an - * array of removed elements. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * var pulled = _.pullAt(array, [1, 3]); - * - * console.log(array); - * // => ['a', 'c'] - * - * console.log(pulled); - * // => ['b', 'd'] - */ - var pullAt = baseRest(function(array, indexes) { - indexes = baseFlatten(indexes, 1); - - var length = array ? array.length : 0, - result = baseAt(array, indexes); - - basePullAt(array, arrayMap(indexes, function(index) { - return isIndex(index, length) ? +index : index; - }).sort(compareAscending)); - - return result; - }); - - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is invoked - * with three arguments: (value, index, array). - * - * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` - * to pull elements from an array by value. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; - * }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate) { - var result = []; - if (!(array && array.length)) { - return result; - } - var index = -1, - indexes = [], - length = array.length; - - predicate = getIteratee(predicate, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } - } - basePullAt(array, indexes); - return result; - } - - /** - * Reverses `array` so that the first element becomes the last, the second - * element becomes the second to last, and so on. - * - * **Note:** This method mutates `array` and is based on - * [`Array#reverse`](https://mdn.io/Array/reverse). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.reverse(array); - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function reverse(array) { - return array ? nativeReverse.call(array) : array; - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of - * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are - * returned. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - else { - start = start == null ? 0 : toInteger(start); - end = end === undefined ? length : toInteger(end); - } - return baseSlice(array, start, end); - } - - /** - * Uses a binary search to determine the lowest index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - */ - function sortedIndex(array, value) { - return baseSortedIndex(array, value); - } - - /** - * This method is like `_.sortedIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); - * // => 0 - */ - function sortedIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); - } - - /** - * This method is like `_.indexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedIndexOf([4, 5, 5, 5, 6], 5); - * // => 1 - */ - function sortedIndexOf(array, value) { - var length = array ? array.length : 0; - if (length) { - var index = baseSortedIndex(array, value); - if (index < length && eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 5, 5, 5, 6], 5); - * // => 4 - */ - function sortedLastIndex(array, value) { - return baseSortedIndex(array, value, true); - } - - /** - * This method is like `_.sortedLastIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 1 - * - * // The `_.property` iteratee shorthand. - * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); - * // => 1 - */ - function sortedLastIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); - } - - /** - * This method is like `_.lastIndexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); - * // => 3 - */ - function sortedLastIndexOf(array, value) { - var length = array ? array.length : 0; - if (length) { - var index = baseSortedIndex(array, value, true) - 1; - if (eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.uniq` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniq([1, 1, 2]); - * // => [1, 2] - */ - function sortedUniq(array) { - return (array && array.length) - ? baseSortedUniq(array) - : []; - } - - /** - * This method is like `_.uniqBy` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); - * // => [1.1, 2.3] - */ - function sortedUniqBy(array, iteratee) { - return (array && array.length) - ? baseSortedUniq(array, getIteratee(iteratee, 2)) - : []; - } - - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.tail([1, 2, 3]); - * // => [2, 3] - */ - function tail(array) { - return drop(array, 1); - } - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - if (!(array && array.length)) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.takeRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeRightWhile(users, ['active', false]); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.takeRightWhile(users, 'active'); - * // => [] - */ - function takeRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), false, true) - : []; - } - - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false}, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.takeWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matches` iteratee shorthand. - * _.takeWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeWhile(users, ['active', false]); - * // => objects for ['barney', 'fred'] - * - * // The `_.property` iteratee shorthand. - * _.takeWhile(users, 'active'); - * // => [] - */ - function takeWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3)) - : []; - } - - /** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ - var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); - }); - - /** - * This method is like `_.union` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which uniqueness is computed. Result values are chosen from the first - * array in which the value occurs. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.unionBy([2.1], [1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - var unionBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.union` except that it accepts `comparator` which - * is invoked to compare elements of `arrays`. Result values are chosen from - * the first array in which the value occurs. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.unionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var unionWith = baseRest(function(arrays) { - var comparator = last(arrays); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each - * element is kept. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ - function uniq(array) { - return (array && array.length) - ? baseUniq(array) - : []; - } - - /** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniqBy(array, iteratee) { - return (array && array.length) - ? baseUniq(array, getIteratee(iteratee, 2)) - : []; - } - - /** - * This method is like `_.uniq` except that it accepts `comparator` which - * is invoked to compare elements of `array`. The comparator is invoked with - * two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.uniqWith(objects, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] - */ - function uniqWith(array, comparator) { - return (array && array.length) - ? baseUniq(array, undefined, comparator) - : []; - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); - } - - /** - * This method is like `_.unzip` except that it accepts `iteratee` to specify - * how regrouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee=_.identity] The function to combine - * regrouped values. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ - function unzipWith(array, iteratee) { - if (!(array && array.length)) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - return arrayMap(result, function(group) { - return apply(iteratee, undefined, group); - }); - } - - /** - * Creates an array excluding all given values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.pull`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.xor - * @example - * - * _.without([2, 1, 2, 3], 1, 2); - * // => [3] - */ - var without = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, values) - : []; - }); - - /** - * Creates an array of unique values that is the - * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the given arrays. The order of result values is determined by the order - * they occur in the arrays. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.without - * @example - * - * _.xor([2, 1], [2, 3]); - * // => [1, 3] - */ - var xor = baseRest(function(arrays) { - return baseXor(arrayFilter(arrays, isArrayLikeObject)); - }); - - /** - * This method is like `_.xor` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which by which they're compared. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2, 3.4] - * - * // The `_.property` iteratee shorthand. - * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var xorBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.xor` except that it accepts `comparator` which is - * invoked to compare elements of `arrays`. The comparator is invoked with - * two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.xorWith(objects, others, _.isEqual); - * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var xorWith = baseRest(function(arrays) { - var comparator = last(arrays); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); - }); - - /** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ - var zip = baseRest(unzip); - - /** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - function zipObject(props, values) { - return baseZipObject(props || [], values || [], assignValue); - } - - /** - * This method is like `_.zipObject` except that it supports property paths. - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); - * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } - */ - function zipObjectDeep(props, values) { - return baseZipObject(props || [], values || [], baseSet); - } - - /** - * This method is like `_.zip` except that it accepts `iteratee` to specify - * how grouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee=_.identity] The function to combine grouped values. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { - * return a + b + c; - * }); - * // => [111, 222] - */ - var zipWith = baseRest(function(arrays) { - var length = arrays.length, - iteratee = length > 1 ? arrays[length - 1] : undefined; - - iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; - return unzipWith(arrays, iteratee); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` wrapper instance that wraps `value` with explicit method - * chain sequences enabled. The result of such sequences must be unwrapped - * with `_#value`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Seq - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _ - * .chain(users) - * .sortBy('age') - * .map(function(o) { - * return o.user + ' is ' + o.age; - * }) - * .head() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor - * is invoked with one argument; (value). The purpose of this method is to - * "tap into" a method chain sequence in order to modify intermediate results. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * // Mutate input array. - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor) { - interceptor(value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * The purpose of this method is to "pass thru" values replacing intermediate - * results in a method chain sequence. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor) { - return interceptor(value); - } - - /** - * This method is the wrapper version of `_.at`. - * - * @name at - * @memberOf _ - * @since 1.0.0 - * @category Seq - * @param {...(string|string[])} [paths] The property paths of elements to pick. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _(object).at(['a[0].b.c', 'a[1]']).value(); - * // => [3, 4] - */ - var wrapperAt = baseRest(function(paths) { - paths = baseFlatten(paths, 1); - var length = paths.length, - start = length ? paths[0] : 0, - value = this.__wrapped__, - interceptor = function(object) { return baseAt(object, paths); }; - - if (length > 1 || this.__actions__.length || - !(value instanceof LazyWrapper) || !isIndex(start)) { - return this.thru(interceptor); - } - value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ - 'func': thru, - 'args': [interceptor], - 'thisArg': undefined - }); - return new LodashWrapper(value, this.__chain__).thru(function(array) { - if (length && !array.length) { - array.push(undefined); - } - return array; - }); - }); - - /** - * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. - * - * @name chain - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // A sequence without explicit chaining. - * _(users).head(); - * // => { 'user': 'barney', 'age': 36 } - * - * // A sequence with explicit chaining. - * _(users) - * .chain() - * .head() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chain sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Gets the next value on a wrapped object following the - * [iterator protocol](https://mdn.io/iteration_protocols#iterator). - * - * @name next - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the next iterator value. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped.next(); - * // => { 'done': false, 'value': 1 } - * - * wrapped.next(); - * // => { 'done': false, 'value': 2 } - * - * wrapped.next(); - * // => { 'done': true, 'value': undefined } - */ - function wrapperNext() { - if (this.__values__ === undefined) { - this.__values__ = toArray(this.value()); - } - var done = this.__index__ >= this.__values__.length, - value = done ? undefined : this.__values__[this.__index__++]; - - return { 'done': done, 'value': value }; - } - - /** - * Enables the wrapper to be iterable. - * - * @name Symbol.iterator - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the wrapper object. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped[Symbol.iterator]() === wrapped; - * // => true - * - * Array.from(wrapped); - * // => [1, 2] - */ - function wrapperToIterator() { - return this; - } - - /** - * Creates a clone of the chain sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @param {*} value The value to plant. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2]).map(square); - * var other = wrapped.plant([3, 4]); - * - * other.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - clone.__index__ = 0; - clone.__values__ = undefined; - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * This method is the wrapper version of `_.reverse`. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ - 'func': thru, - 'args': [reverse], - 'thisArg': undefined - }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(reverse); - } - - /** - * Executes the chain sequence to resolve the unwrapped value. - * - * @name value - * @memberOf _ - * @since 0.1.0 - * @alias toJSON, valueOf - * @category Seq - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the number of times the key was returned by `iteratee`. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': 1, '6': 2 } - * - * // The `_.property` iteratee shorthand. - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * Iteration is stopped once `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.every(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, guard) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - */ - function filter(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ - var find = createFind(findIndex); - - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=collection.length-1] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; - * }); - * // => 3 - */ - var findLast = createFind(findLastIndex); - - /** - * Creates a flattened array of values by running each element in `collection` - * thru `iteratee` and flattening the mapped results. The iteratee is invoked - * with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [n, n]; - * } - * - * _.flatMap([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee), 1); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDeep([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMapDeep(collection, iteratee) { - return baseFlatten(map(collection, iteratee), INFINITY); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDepth([1, 2], duplicate, 2); - * // => [[1, 1], [2, 2]] - */ - function flatMapDepth(collection, iteratee, depth) { - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(map(collection, iteratee), depth); - } - - /** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _([1, 2]).forEach(function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @alias eachRight - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEach - * @example - * - * _.forEachRight([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `2` then `1`. - */ - function forEachRight(collection, iteratee) { - var func = isArray(collection) ? arrayEachRight : baseEachRight; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - result[key] = [value]; - } - }); - - /** - * Checks if `value` is in `collection`. If `collection` is a string, it's - * checked for a substring of `value`, otherwise - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * is used for equality comparisons. If `fromIndex` is negative, it's used as - * the offset from the end of `collection`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {boolean} Returns `true` if `value` is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'a': 1, 'b': 2 }, 1); - * // => true - * - * _.includes('abcd', 'bc'); - * // => true - */ - function includes(collection, value, fromIndex, guard) { - collection = isArrayLike(collection) ? collection : values(collection); - fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; - - var length = collection.length; - if (fromIndex < 0) { - fromIndex = nativeMax(length + fromIndex, 0); - } - return isString(collection) - ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) - : (!!length && baseIndexOf(collection, value, fromIndex) > -1); - } - - /** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `path` is a function, it's invoked - * for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke each method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invokeMap([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - var invokeMap = baseRest(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - isProp = isKey(path), - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); - result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); - }); - return result; - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the last element responsible for generating the key. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var array = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.keyBy(array, function(o) { - * return String.fromCharCode(o.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.keyBy(array, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - */ - var keyBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee) { - var func = isArray(collection) ? arrayMap : baseMap; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.sortBy` except that it allows specifying the sort - * orders of the iteratees to sort by. If `orders` is unspecified, all values - * are sorted in ascending order. Otherwise, specify an order of "desc" for - * descending or "asc" for ascending sort order of corresponding values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] - * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // Sort by `user` in ascending order and by `age` in descending order. - * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - function orderBy(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - orders = guard ? undefined : orders; - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseOrderBy(collection, iteratees, orders); - } - - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, the second of which - * contains elements `predicate` returns falsey for. The predicate is - * invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.partition(users, function(o) { return o.active; }); - * // => objects for [['fred'], ['barney', 'pebbles']] - * - * // The `_.matches` iteratee shorthand. - * _.partition(users, { 'age': 1, 'active': false }); - * // => objects for [['pebbles'], ['barney', 'fred']] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.partition(users, ['active', false]); - * // => objects for [['barney', 'pebbles'], ['fred']] - * - * // The `_.property` iteratee shorthand. - * _.partition(users, 'active'); - * // => objects for [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduce : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); - } - - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduce - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduceRight : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); - } - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.filter - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * _.reject(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.reject(users, { 'age': 40, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.reject(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.reject(users, 'active'); - * // => objects for ['barney'] - */ - function reject(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, negate(getIteratee(predicate, 3))); - } - - /** - * Gets a random element from `collection`. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - */ - function sample(collection) { - var array = isArrayLike(collection) ? collection : values(collection), - length = array.length; - - return length > 0 ? array[baseRandom(0, length - 1)] : undefined; - } - - /** - * Gets `n` random elements at unique keys from `collection` up to the - * size of `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @param {number} [n=1] The number of elements to sample. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the random elements. - * @example - * - * _.sampleSize([1, 2, 3], 2); - * // => [3, 1] - * - * _.sampleSize([1, 2, 3], 4); - * // => [2, 3, 1] - */ - function sampleSize(collection, n, guard) { - var index = -1, - result = toArray(collection), - length = result.length, - lastIndex = length - 1; - - if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { - n = 1; - } else { - n = baseClamp(toInteger(n), 0, length); - } - while (++index < n) { - var rand = baseRandom(index, lastIndex), - value = result[rand]; - - result[rand] = result[index]; - result[index] = value; - } - result.length = n; - return result; - } - - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - return sampleSize(collection, MAX_ARRAY_LENGTH); - } - - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - var result = collection.length; - return (result && isString(collection)) ? stringSize(collection) : result; - } - if (isObjectLike(collection)) { - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - } - return keys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * Iteration is stopped once `predicate` returns truthy. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.some(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, guard) { - var func = isArray(collection) ? arraySome : baseSome; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection thru each iteratee. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The iteratees are invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to sort by. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.sortBy(users, function(o) { return o.user; }); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - * - * _.sortBy(users, ['user', 'age']); - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] - * - * _.sortBy(users, 'user', function(o) { - * return Math.floor(o.age / 10); - * }); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - var sortBy = baseRest(function(collection, iteratees) { - if (collection == null) { - return []; - } - var length = iteratees.length; - if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { - iteratees = []; - } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { - iteratees = [iteratees[0]]; - } - return baseOrderBy(collection, baseFlatten(iteratees, 1), []); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Gets the timestamp of the number of milliseconds that have elapsed since - * the Unix epoch (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Date - * @returns {number} Returns the timestamp. - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred invocation. - */ - function now() { - return Date.now(); - } - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it's called `n` or more times. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => Logs 'done saving!' after the two async saves have completed. - */ - function after(n, func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that invokes `func`, with up to `n` arguments, - * ignoring any additional arguments. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - n = guard ? undefined : n; - n = (func && n == null) ? func.length : n; - return createWrap(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it's called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery(element).on('click', _.before(5, addContactToList)); - * // => Allows adding up to 4 contacts to the list. - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and `partials` prepended to the arguments it receives. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * function greet(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // Bound with placeholders. - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = baseRest(function(func, thisArg, partials) { - var bitmask = BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bind)); - bitmask |= PARTIAL_FLAG; - } - return createWrap(func, bitmask, thisArg, partials, holders); - }); - - /** - * Creates a function that invokes the method at `object[key]` with `partials` - * prepended to the arguments it receives. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. See - * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Function - * @param {Object} object The object to invoke the method on. - * @param {string} key The key of the method. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // Bound with placeholders. - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = baseRest(function(object, key, partials) { - var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bindKey)); - bitmask |= PARTIAL_FLAG; - } - return createWrap(key, bitmask, object, partials, holders); - }); - - /** - * Creates a function that accepts arguments of `func` and either invokes - * `func` returning its result, if at least `arity` number of arguments have - * been provided, or returns a function that accepts the remaining `func` - * arguments, and so on. The arity of `func` may be specified if `func.length` - * is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - function curry(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curry.placeholder; - return result; - } - - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - function curryRight(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryRight.placeholder; - return result; - } - - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed `func` invocations and a `flush` method to immediately invoke them. - * Provide `options` to indicate whether `func` should be invoked on the - * leading and/or trailing edge of the `wait` timeout. The `func` is invoked - * with the last arguments provided to the debounced function. Subsequent - * calls to the debounced function return the result of the last `func` - * invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the debounced function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=false] - * Specify invoking on the leading edge of the timeout. - * @param {number} [options.maxWait] - * The maximum time `func` is allowed to be delayed before it's invoked. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // Avoid costly calculations while the window size is in flux. - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // Invoke `sendMail` when clicked, debouncing subsequent calls. - * jQuery(element).on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // Ensure `batchLog` is invoked once after 1 second of debounced calls. - * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); - * var source = new EventSource('/stream'); - * jQuery(source).on('message', debounced); - * - * // Cancel the trailing debounced invocation. - * jQuery(window).on('popstate', debounced.cancel); - */ - function debounce(func, wait, options) { - var lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime, - lastInvokeTime = 0, - leading = false, - maxing = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject(options)) { - leading = !!options.leading; - maxing = 'maxWait' in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - - function invokeFunc(time) { - var args = lastArgs, - thisArg = lastThis; - - lastArgs = lastThis = undefined; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } - - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time; - // Start the timer for the trailing edge. - timerId = setTimeout(timerExpired, wait); - // Invoke the leading edge. - return leading ? invokeFunc(time) : result; - } - - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime, - result = wait - timeSinceLastCall; - - return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; - } - - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime; - - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); - } - - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - // Restart the timer. - timerId = setTimeout(timerExpired, remainingWait(time)); - } - - function trailingEdge(time) { - timerId = undefined; - - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = undefined; - return result; - } - - function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = undefined; - } - - function flush() { - return timerId === undefined ? result : trailingEdge(now()); - } - - function debounced() { - var time = now(), - isInvoking = shouldInvoke(time); - - lastArgs = arguments; - lastThis = this; - lastCallTime = time; - - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime); - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === undefined) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // => Logs 'deferred' after one or more milliseconds. - */ - var defer = baseRest(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => Logs 'later' after one second. - */ - var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber(wait) || 0, args); - }); - - /** - * Creates a function that invokes `func` with arguments reversed. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to flip arguments for. - * @returns {Function} Returns the new flipped function. - * @example - * - * var flipped = _.flip(function() { - * return _.toArray(arguments); - * }); - * - * flipped('a', 'b', 'c', 'd'); - * // => ['d', 'c', 'b', 'a'] - */ - function flip(func) { - return createWrap(func, FLIP_FLAG); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) - * method interface of `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result); - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Assign cache to `_.memoize`. - memoize.Cache = MapCache; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first invocation. The `func` is - * invoked with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // => `createApplication` is invoked once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with its arguments transformed. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms=[_.identity]] - * The argument transforms. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var func = _.overArgs(function(x, y) { - * return [x, y]; - * }, [square, doubled]); - * - * func(9, 3); - * // => [81, 6] - * - * func(10, 5); - * // => [100, 10] - */ - var overArgs = baseRest(function(func, transforms) { - transforms = (transforms.length == 1 && isArray(transforms[0])) - ? arrayMap(transforms[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); - - var funcsLength = transforms.length; - return baseRest(function(args) { - var index = -1, - length = nativeMin(args.length, funcsLength); - - while (++index < length) { - args[index] = transforms[index].call(this, args[index]); - } - return apply(func, this, args); - }); - }); - - /** - * Creates a function that invokes `func` with `partials` prepended to the - * arguments it receives. This method is like `_.bind` except it does **not** - * alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 0.2.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // Partially applied with placeholders. - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partial)); - return createWrap(func, PARTIAL_FLAG, undefined, partials, holders); - }); - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to the arguments it receives. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // Partially applied with placeholders. - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partialRight)); - return createWrap(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); - }); - - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified `indexes` where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, [2, 0, 1]); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - */ - var rearg = baseRest(function(func, indexes) { - return createWrap(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); - }); - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as - * an array. - * - * **Note:** This method is based on the - * [rest parameter](https://mdn.io/rest_parameters). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.rest(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function rest(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? start : toInteger(start); - return baseRest(func, start); - } - - /** - * Creates a function that invokes `func` with the `this` binding of the - * create function and an array of arguments much like - * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply). - * - * **Note:** This method is based on the - * [spread operator](https://mdn.io/spread_operator). - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Function - * @param {Function} func The function to spread arguments over. - * @param {number} [start=0] The start position of the spread. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * numbers.then(_.spread(function(x, y) { - * return x + y; - * })); - * // => a Promise of 76 - */ - function spread(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? 0 : nativeMax(toInteger(start), 0); - return baseRest(function(args) { - var array = args[start], - otherArgs = castSlice(args, 0, start); - - if (array) { - arrayPush(otherArgs, array); - } - return apply(func, this, otherArgs); - }); - } - - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed `func` invocations and a `flush` method to - * immediately invoke them. Provide `options` to indicate whether `func` - * should be invoked on the leading and/or trailing edge of the `wait` - * timeout. The `func` is invoked with the last arguments provided to the - * throttled function. Subsequent calls to the throttled function return the - * result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the throttled function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=true] - * Specify invoking on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // Avoid excessively updating the position while scrolling. - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); - * jQuery(element).on('click', throttled); - * - * // Cancel the trailing throttled invocation. - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { - 'leading': leading, - 'maxWait': wait, - 'trailing': trailing - }); - } - - /** - * Creates a function that accepts up to one argument, ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.unary(parseInt)); - * // => [6, 8, 10] - */ - function unary(func) { - return ary(func, 1); - } - - /** - * Creates a function that provides `value` to `wrapper` as its first - * argument. Any additional arguments provided to the function are appended - * to those provided to the `wrapper`. The wrapper is invoked with the `this` - * binding of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {*} value The value to wrap. - * @param {Function} [wrapper=identity] The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '

' + func(text) + '

'; - * }); - * - * p('fred, barney, & pebbles'); - * // => '

fred, barney, & pebbles

' - */ - function wrap(value, wrapper) { - wrapper = wrapper == null ? identity : wrapper; - return partial(wrapper, value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Casts `value` as an array if it's not one. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Lang - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast array. - * @example - * - * _.castArray(1); - * // => [1] - * - * _.castArray({ 'a': 1 }); - * // => [{ 'a': 1 }] - * - * _.castArray('abc'); - * // => ['abc'] - * - * _.castArray(null); - * // => [null] - * - * _.castArray(undefined); - * // => [undefined] - * - * _.castArray(); - * // => [] - * - * var array = [1, 2, 3]; - * console.log(_.castArray(array) === array); - * // => true - */ - function castArray() { - if (!arguments.length) { - return []; - } - var value = arguments[0]; - return isArray(value) ? value : [value]; - } - - /** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ - function clone(value) { - return baseClone(value, false, true); - } - - /** - * This method is like `_.clone` except that it accepts `customizer` which - * is invoked to produce the cloned value. If `customizer` returns `undefined`, - * cloning is handled by the method instead. The `customizer` is invoked with - * up to four arguments; (value [, index|key, object, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the cloned value. - * @see _.cloneDeepWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * } - * - * var el = _.cloneWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 0 - */ - function cloneWith(value, customizer) { - return baseClone(value, false, true, customizer); - } - - /** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ - function cloneDeep(value) { - return baseClone(value, true, true); - } - - /** - * This method is like `_.cloneWith` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the deep cloned value. - * @see _.cloneWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * } - * - * var el = _.cloneDeepWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 20 - */ - function cloneDeepWith(value, customizer) { - return baseClone(value, true, true, customizer); - } - - /** - * Checks if `object` conforms to `source` by invoking the predicate - * properties of `source` with the corresponding property values of `object`. - * - * **Note:** This method is equivalent to `_.conforms` when `source` is - * partially applied. - * - * @static - * @memberOf _ - * @since 4.14.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); - * // => true - * - * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); - * // => false - */ - function conformsTo(object, source) { - return source == null || baseConformsTo(object, source, keys(source)); - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** - * Checks if `value` is greater than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - * @see _.lt - * @example - * - * _.gt(3, 1); - * // => true - * - * _.gt(3, 3); - * // => false - * - * _.gt(1, 3); - * // => false - */ - var gt = createRelationalOperation(baseGt); - - /** - * Checks if `value` is greater than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than or equal to - * `other`, else `false`. - * @see _.lte - * @example - * - * _.gte(3, 1); - * // => true - * - * _.gte(3, 3); - * // => true - * - * _.gte(1, 3); - * // => false - */ - var gte = createRelationalOperation(function(value, other) { - return value >= other; - }); - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** - * Checks if `value` is classified as an `ArrayBuffer` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - * @example - * - * _.isArrayBuffer(new ArrayBuffer(2)); - * // => true - * - * _.isArrayBuffer(new Array(2)); - * // => false - */ - var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(getLength(value)) && !isFunction(value); - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && objectToString.call(value) == boolTag); - } - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; - - /** - * Checks if `value` is likely a DOM element. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, - * else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement(''); - * // => false - */ - function isElement(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - } - - /** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (isArrayLike(value) && - (isArray(value) || isString(value) || isFunction(value.splice) || - isArguments(value) || isBuffer(value))) { - return !value.length; - } - if (isObjectLike(value)) { - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { - return !value.size; - } - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return !(nonEnumShadows && keys(value).length); - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are **not** supported. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, - * else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** - * This method is like `_.isEqual` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with up to - * six arguments: (objValue, othValue [, index|key, object, other, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if the values are equivalent, - * else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, othValue) { - * if (isGreeting(objValue) && isGreeting(othValue)) { - * return true; - * } - * } - * - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqualWith(array, other, customizer); - * // => true - */ - function isEqualWith(value, other, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, - * else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - if (!isObjectLike(value)) { - return false; - } - return (objectToString.call(value) == errorTag) || - (typeof value.message == 'string' && typeof value.name == 'string'); - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on - * [`Number.isFinite`](https://mdn.io/Number/isFinite). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, - * else `false`. - * @example - * - * _.isFinite(3); - * // => true - * - * _.isFinite(Number.MIN_VALUE); - * // => true - * - * _.isFinite(Infinity); - * // => false - * - * _.isFinite('3'); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8 which returns 'object' for typed array and weak map constructors, - // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; - } - - /** - * Checks if `value` is an integer. - * - * **Note:** This method is based on - * [`Number.isInteger`](https://mdn.io/Number/isInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an integer, else `false`. - * @example - * - * _.isInteger(3); - * // => true - * - * _.isInteger(Number.MIN_VALUE); - * // => false - * - * _.isInteger(Infinity); - * // => false - * - * _.isInteger('3'); - * // => false - */ - function isInteger(value) { - return typeof value == 'number' && value == toInteger(value); - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, - * else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return !!value && typeof value == 'object'; - } - - /** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - - /** - * Performs a partial deep comparison between `object` and `source` to - * determine if `object` contains equivalent property values. - * - * **Note:** This method supports comparing the same values as `_.isEqual` - * and is equivalent to `_.matches` when `source` is partially applied. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.isMatch(object, { 'b': 2 }); - * // => true - * - * _.isMatch(object, { 'b': 1 }); - * // => false - */ - function isMatch(object, source) { - return object === source || baseIsMatch(object, source, getMatchData(source)); - } - - /** - * This method is like `_.isMatch` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with five - * arguments: (objValue, srcValue, index|key, object, source). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, srcValue) { - * if (isGreeting(objValue) && isGreeting(srcValue)) { - * return true; - * } - * } - * - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatchWith(object, source, customizer); - * // => true - */ - function isMatchWith(object, source, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseIsMatch(object, source, getMatchData(source), customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a pristine native function. - * - * **Note:** This method can't reliably detect native functions in the presence - * of the core-js package because core-js circumvents this kind of detection. - * Despite multiple requests, the core-js maintainer has made it clear: any - * attempt to fix the detection will be obstructed. As a result, we're left - * with little choice but to throw an error. Unfortunately, this also affects - * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), - * which rely on core-js. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (isMaskable(value)) { - throw new Error('This method is not supported with core-js. Try https://github.com/es-shims.'); - } - return baseIsNative(value); - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is `null` or `undefined`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is nullish, else `false`. - * @example - * - * _.isNil(null); - * // => true - * - * _.isNil(void 0); - * // => true - * - * _.isNil(NaN); - * // => false - */ - function isNil(value) { - return value == null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && objectToString.call(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, - * else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || - objectToString.call(value) != objectTag || isHostObject(value)) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return (typeof Ctor == 'function' && - Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); - } - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; - - /** - * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 - * double precision number which isn't the result of a rounded unsafe integer. - * - * **Note:** This method is based on - * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a safe integer, - * else `false`. - * @example - * - * _.isSafeInteger(3); - * // => true - * - * _.isSafeInteger(Number.MIN_VALUE); - * // => false - * - * _.isSafeInteger(Infinity); - * // => false - * - * _.isSafeInteger('3'); - * // => false - */ - function isSafeInteger(value) { - return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); - } - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && objectToString.call(value) == symbolTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Checks if `value` is classified as a `WeakMap` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. - * @example - * - * _.isWeakMap(new WeakMap); - * // => true - * - * _.isWeakMap(new Map); - * // => false - */ - function isWeakMap(value) { - return isObjectLike(value) && getTag(value) == weakMapTag; - } - - /** - * Checks if `value` is classified as a `WeakSet` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. - * @example - * - * _.isWeakSet(new WeakSet); - * // => true - * - * _.isWeakSet(new Set); - * // => false - */ - function isWeakSet(value) { - return isObjectLike(value) && objectToString.call(value) == weakSetTag; - } - - /** - * Checks if `value` is less than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - * @see _.gt - * @example - * - * _.lt(1, 3); - * // => true - * - * _.lt(3, 3); - * // => false - * - * _.lt(3, 1); - * // => false - */ - var lt = createRelationalOperation(baseLt); - - /** - * Checks if `value` is less than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than or equal to - * `other`, else `false`. - * @see _.gte - * @example - * - * _.lte(1, 3); - * // => true - * - * _.lte(3, 3); - * // => true - * - * _.lte(3, 1); - * // => false - */ - var lte = createRelationalOperation(function(value, other) { - return value <= other; - }); - - /** - * Converts `value` to an array. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [1, 2] - * - * _.toArray('abc'); - * // => ['a', 'b', 'c'] - * - * _.toArray(1); - * // => [] - * - * _.toArray(null); - * // => [] - */ - function toArray(value) { - if (!value) { - return []; - } - if (isArrayLike(value)) { - return isString(value) ? stringToArray(value) : copyArray(value); - } - if (iteratorSymbol && value[iteratorSymbol]) { - return iteratorToArray(value[iteratorSymbol]()); - } - var tag = getTag(value), - func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); - - return func(value); - } - - /** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - - /** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ - function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; - } - - /** - * Converts `value` to an integer suitable for use as the length of an - * array-like object. - * - * **Note:** This method is based on - * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toLength(3.2); - * // => 3 - * - * _.toLength(Number.MIN_VALUE); - * // => 0 - * - * _.toLength(Infinity); - * // => 4294967295 - * - * _.toLength('3.2'); - * // => 3 - */ - function toLength(value) { - return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; - } - - /** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ - function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = isFunction(value.valueOf) ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * Converts `value` to a safe integer. A safe integer can be compared and - * represented correctly. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toSafeInteger(3.2); - * // => 3 - * - * _.toSafeInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toSafeInteger(Infinity); - * // => 9007199254740991 - * - * _.toSafeInteger('3.2'); - * // => 3 - */ - function toSafeInteger(value) { - return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); - } - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {string} Returns the string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ - var assign = createAssigner(function(object, source) { - if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } - }); - - /** - * This method is like `_.assign` except that it iterates over own and - * inherited source properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assign - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assignIn({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } - */ - var assignIn = createAssigner(function(object, source) { - if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { - copyObject(source, keysIn(source), object); - return; - } - for (var key in source) { - assignValue(object, key, source[key]); - } - }); - - /** - * This method is like `_.assignIn` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extendWith - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignInWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keysIn(source), object, customizer); - }); - - /** - * This method is like `_.assign` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignInWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keys(source), object, customizer); - }); - - /** - * Creates an array of values corresponding to `paths` of `object`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {...(string|string[])} [paths] The property paths of elements to pick. - * @returns {Array} Returns the picked values. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _.at(object, ['a[0].b.c', 'a[1]']); - * // => [3, 4] - */ - var at = baseRest(function(object, paths) { - return baseAt(object, baseFlatten(paths, 1)); - }); - - /** - * Creates an object that inherits from the `prototype` object. If a - * `properties` object is given, its own enumerable string keyed properties - * are assigned to the created object. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? baseAssign(result, properties) : result; - } - - /** - * Assigns own and inherited enumerable string keyed properties of source - * objects to the destination object for all destination properties that - * resolve to `undefined`. Source objects are applied from left to right. - * Once a property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaultsDeep - * @example - * - * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var defaults = baseRest(function(args) { - args.push(undefined, assignInDefaults); - return apply(assignInWith, undefined, args); - }); - - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ - var defaultsDeep = baseRest(function(args) { - args.push(undefined, mergeDefaults); - return apply(mergeWith, undefined, args); - }); - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to search. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to search. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(o) { return o.age < 40; }); - * // => returns 'pebbles' assuming `_.findKey` returns 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); - } - - /** - * Iterates over own and inherited enumerable string keyed properties of an - * object and invokes `iteratee` for each property. The iteratee is invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forInRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). - */ - function forIn(object, iteratee) { - return object == null - ? object - : baseFor(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forIn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. - */ - function forInRight(object, iteratee) { - return object == null - ? object - : baseForRight(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * Iterates over own enumerable string keyed properties of an object and - * invokes `iteratee` for each property. The iteratee is invoked with three - * arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwnRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forOwn(object, iteratee) { - return object && baseForOwn(object, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. - */ - function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, getIteratee(iteratee, 3)); - } - - /** - * Creates an array of function property names from own enumerable properties - * of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functionsIn - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functions(new Foo); - * // => ['a', 'b'] - */ - function functions(object) { - return object == null ? [] : baseFunctions(object, keys(object)); - } - - /** - * Creates an array of function property names from own and inherited - * enumerable properties of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functions - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functionsIn(new Foo); - * // => ['a', 'b', 'c'] - */ - function functionsIn(object) { - return object == null ? [] : baseFunctions(object, keysIn(object)); - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ - function has(object, path) { - return object != null && hasPath(object, path, baseHas); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite - * property assignments of previous values. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Object - * @param {Object} object The object to invert. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - */ - var invert = createInverter(function(result, value, key) { - result[value] = key; - }, constant(identity)); - - /** - * This method is like `_.invert` except that the inverted object is generated - * from the results of running each element of `object` thru `iteratee`. The - * corresponding inverted value of each inverted key is an array of keys - * responsible for generating the inverted value. The iteratee is invoked - * with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Object - * @param {Object} object The object to invert. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invertBy(object); - * // => { '1': ['a', 'c'], '2': ['b'] } - * - * _.invertBy(object, function(value) { - * return 'group' + value; - * }); - * // => { 'group1': ['a', 'c'], 'group2': ['b'] } - */ - var invertBy = createInverter(function(result, value, key) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - }, getIteratee); - - /** - * Invokes the method at `path` of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - * @example - * - * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; - * - * _.invoke(object, 'a[0].b.c.slice', 1, 3); - * // => [2, 3] - */ - var invoke = baseRest(baseInvoke); - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - var isProto = isPrototype(object); - if (!(isProto || isArrayLike(object))) { - return baseKeys(object); - } - var indexes = indexKeys(object), - skipIndexes = !!indexes, - result = indexes || [], - length = result.length; - - for (var key in object) { - if (baseHas(object, key) && - !(skipIndexes && (key == 'length' || isIndex(key, length))) && - !(isProto && key == 'constructor')) { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - var index = -1, - isProto = isPrototype(object), - props = baseKeysIn(object), - propsLength = props.length, - indexes = indexKeys(object), - skipIndexes = !!indexes, - result = indexes || [], - length = result.length; - - while (++index < propsLength) { - var key = props[index]; - if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - result[iteratee(value, key, object)] = value; - }); - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - result[key] = iteratee(value, key, object); - }); - return result; - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with seven arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ - var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); - }); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable string keyed properties of `object` that are - * not omitted. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [props] The property identifiers to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ - var omit = baseRest(function(object, props) { - if (object == null) { - return {}; - } - props = arrayMap(baseFlatten(props, 1), toKey); - return basePick(object, baseDifference(getAllKeysIn(object), props)); - }); - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(getIteratee(predicate))); - } - - /** - * Creates an object composed of the picked `object` properties. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [props] The property identifiers to pick. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pick(object, ['a', 'c']); - * // => { 'a': 1, 'c': 3 } - */ - var pick = baseRest(function(object, props) { - return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); - }); - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - return object == null ? {} : basePickBy(object, getAllKeysIn(object), getIteratee(predicate)); - } - - /** - * This method is like `_.get` except that if the resolved value is a - * function it's invoked with the `this` binding of its parent object and - * its result is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a[0].b.c3', 'default'); - * // => 'default' - * - * _.result(object, 'a[0].b.c3', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = -1, - length = path.length; - - // Ensure the loop is entered when path is empty. - if (!length) { - object = undefined; - length = 1; - } - while (++index < length) { - var value = object == null ? undefined : object[toKey(path[index])]; - if (value === undefined) { - index = length; - value = defaultValue; - } - object = isFunction(value) ? value.call(object) : value; - } - return object; - } - - /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); - } - - /** - * This method is like `_.set` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.setWith(object, '[0][1]', 'a', Object); - * // => { '0': { '1': 'a' } } - */ - function setWith(object, path, value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseSet(object, path, value, customizer); - } - - /** - * Creates an array of own enumerable string keyed-value pairs for `object` - * which can be consumed by `_.fromPairs`. If `object` is a map or set, its - * entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entries - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairs(new Foo); - * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) - */ - var toPairs = createToPairs(keys); - - /** - * Creates an array of own and inherited enumerable string keyed-value pairs - * for `object` which can be consumed by `_.fromPairs`. If `object` is a map - * or set, its entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entriesIn - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairsIn(new Foo); - * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) - */ - var toPairsIn = createToPairs(keysIn); - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. If `accumulator` is not - * provided, a new object with the same `[[Prototype]]` will be used. The - * iteratee is invoked with four arguments: (accumulator, value, key, object). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }, []); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function transform(object, iteratee, accumulator) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = getIteratee(iteratee, 4); - - if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; - } - } else { - accumulator = {}; - } - } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Removes the property at `path` of `object`. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 7 } }] }; - * _.unset(object, 'a[0].b.c'); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - * - * _.unset(object, ['a', '0', 'b', 'c']); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - */ - function unset(object, path) { - return object == null ? true : baseUnset(object, path); - } - - /** - * This method is like `_.set` except that accepts `updater` to produce the - * value to set. Use `_.updateWith` to customize `path` creation. The `updater` - * is invoked with one argument: (value). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.update(object, 'a[0].b.c', function(n) { return n * n; }); - * console.log(object.a[0].b.c); - * // => 9 - * - * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); - * console.log(object.x[0].y.z); - * // => 0 - */ - function update(object, path, updater) { - return object == null ? object : baseUpdate(object, path, castFunction(updater)); - } - - /** - * This method is like `_.update` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.updateWith(object, '[0][1]', _.constant('a'), Object); - * // => { '0': { '1': 'a' } } - */ - function updateWith(object, path, updater, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); - } - - /** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return object ? baseValues(object, keys(object)) : []; - } - - /** - * Creates an array of the own and inherited enumerable string keyed property - * values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return object == null ? [] : baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Clamps `number` within the inclusive `lower` and `upper` bounds. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Number - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - * @example - * - * _.clamp(-10, -5, 5); - * // => -5 - * - * _.clamp(10, -5, 5); - * // => 5 - */ - function clamp(number, lower, upper) { - if (upper === undefined) { - upper = lower; - lower = undefined; - } - if (upper !== undefined) { - upper = toNumber(upper); - upper = upper === upper ? upper : 0; - } - if (lower !== undefined) { - lower = toNumber(lower); - lower = lower === lower ? lower : 0; - } - return baseClamp(toNumber(number), lower, upper); - } - - /** - * Checks if `n` is between `start` and up to, but not including, `end`. If - * `end` is not specified, it's set to `start` with `start` then set to `0`. - * If `start` is greater than `end` the params are swapped to support - * negative ranges. - * - * @static - * @memberOf _ - * @since 3.3.0 - * @category Number - * @param {number} number The number to check. - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - * @see _.range, _.rangeRight - * @example - * - * _.inRange(3, 2, 4); - * // => true - * - * _.inRange(4, 8); - * // => true - * - * _.inRange(4, 2); - * // => false - * - * _.inRange(2, 2); - * // => false - * - * _.inRange(1.2, 2); - * // => true - * - * _.inRange(5.2, 4); - * // => false - * - * _.inRange(-3, -2, -6); - * // => true - */ - function inRange(number, start, end) { - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - number = toNumber(number); - return baseInRange(number, start, end); - } - - /** - * Produces a random number between the inclusive `lower` and `upper` bounds. - * If only one argument is provided a number between `0` and the given number - * is returned. If `floating` is `true`, or either `lower` or `upper` are - * floats, a floating-point number is returned instead of an integer. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Number - * @param {number} [lower=0] The lower bound. - * @param {number} [upper=1] The upper bound. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(lower, upper, floating) { - if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { - upper = floating = undefined; - } - if (floating === undefined) { - if (typeof upper == 'boolean') { - floating = upper; - upper = undefined; - } - else if (typeof lower == 'boolean') { - floating = lower; - lower = undefined; - } - } - if (lower === undefined && upper === undefined) { - lower = 0; - upper = 1; - } - else { - lower = toFinite(lower); - if (upper === undefined) { - upper = lower; - lower = 0; - } else { - upper = toFinite(upper); - } - } - if (lower > upper) { - var temp = lower; - lower = upper; - upper = temp; - } - if (floating || lower % 1 || upper % 1) { - var rand = nativeRandom(); - return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); - } - return baseRandom(lower, upper); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar--'); - * // => 'fooBar' - * - * _.camelCase('__FOO_BAR__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? capitalize(word) : word); - }); - - /** - * Converts the first character of `string` to upper case and the remaining - * to lower case. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('FRED'); - * // => 'Fred' - */ - function capitalize(string) { - return upperFirst(toString(string).toLowerCase()); - } - - /** - * Deburrs `string` by converting - * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * to basic latin letters and removing - * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('déjà vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = toString(string); - return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search up to. - * @returns {boolean} Returns `true` if `string` ends with `target`, - * else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = toString(string); - target = baseToString(target); - - var length = string.length; - position = position === undefined - ? length - : baseClamp(toInteger(position), 0, length); - - var end = position; - position -= target.length; - return position >= 0 && string.slice(position, end) == target; - } - - /** - * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to - * their corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional - * characters use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. See - * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * Backticks are escaped because in IE < 9, they can break out of - * attribute values or HTML comments. See [#59](https://html5sec.org/#59), - * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and - * [#133](https://html5sec.org/#133) of the - * [HTML5 Security Cheatsheet](https://html5sec.org/) for more details. - * - * When working with HTML you should always - * [quote attribute values](http://wonko.com/post/html-escaping) to reduce - * XSS vectors. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - string = toString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", - * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ - function escapeRegExp(string) { - string = toString(string); - return (string && reHasRegExpChar.test(string)) - ? string.replace(reRegExpChar, '\\$&') - : string; - } - - /** - * Converts `string` to - * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__FOO_BAR__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); - }); - - /** - * Converts `string`, as space separated words, to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the lower cased string. - * @example - * - * _.lowerCase('--Foo-Bar--'); - * // => 'foo bar' - * - * _.lowerCase('fooBar'); - * // => 'foo bar' - * - * _.lowerCase('__FOO_BAR__'); - * // => 'foo bar' - */ - var lowerCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + word.toLowerCase(); - }); - - /** - * Converts the first character of `string` to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.lowerFirst('Fred'); - * // => 'fred' - * - * _.lowerFirst('FRED'); - * // => 'fRED' - */ - var lowerFirst = createCaseFirst('toLowerCase'); - - /** - * Pads `string` on the left and right sides if it's shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - if (!length || strLength >= length) { - return string; - } - var mid = (length - strLength) / 2; - return ( - createPadding(nativeFloor(mid), chars) + - string + - createPadding(nativeCeil(mid), chars) - ); - } - - /** - * Pads `string` on the right side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padEnd('abc', 6); - * // => 'abc ' - * - * _.padEnd('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padEnd('abc', 3); - * // => 'abc' - */ - function padEnd(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (string + createPadding(length - strLength, chars)) - : string; - } - - /** - * Pads `string` on the left side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padStart('abc', 6); - * // => ' abc' - * - * _.padStart('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padStart('abc', 3); - * // => 'abc' - */ - function padStart(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (createPadding(length - strLength, chars) + string) - : string; - } - - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a - * hexadecimal, in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the - * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category String - * @param {string} string The string to convert. - * @param {number} [radix=10] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - // Chrome fails to trim leading whitespace characters. - // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details. - if (guard || radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = toString(string).replace(reTrim, ''); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=1] The number of times to repeat the string. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n, guard) { - if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - return baseRepeat(toString(string), n); - } - - /** - * Replaces matches for `pattern` in `string` with `replacement`. - * - * **Note:** This method is based on - * [`String#replace`](https://mdn.io/String/replace). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to modify. - * @param {RegExp|string} pattern The pattern to replace. - * @param {Function|string} replacement The match replacement. - * @returns {string} Returns the modified string. - * @example - * - * _.replace('Hi Fred', 'Fred', 'Barney'); - * // => 'Hi Barney' - */ - function replace() { - var args = arguments, - string = toString(args[0]); - - return args.length < 3 ? string : nativeReplace.call(string, args[1], args[2]); - } - - /** - * Converts `string` to - * [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--FOO-BAR--'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); - - /** - * Splits `string` by `separator`. - * - * **Note:** This method is based on - * [`String#split`](https://mdn.io/String/split). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to split. - * @param {RegExp|string} separator The separator pattern to split by. - * @param {number} [limit] The length to truncate results to. - * @returns {Array} Returns the string segments. - * @example - * - * _.split('a-b-c', '-', 2); - * // => ['a', 'b'] - */ - function split(string, separator, limit) { - if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { - separator = limit = undefined; - } - limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; - if (!limit) { - return []; - } - string = toString(string); - if (string && ( - typeof separator == 'string' || - (separator != null && !isRegExp(separator)) - )) { - separator = baseToString(separator); - if (separator == '' && reHasComplexSymbol.test(string)) { - return castSlice(stringToArray(string), 0, limit); - } - } - return nativeSplit.call(string, separator, limit); - } - - /** - * Converts `string` to - * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @since 3.1.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar--'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__FOO_BAR__'); - * // => 'FOO BAR' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + upperFirst(word); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, - * else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = toString(string); - position = baseClamp(toInteger(position), 0, string.length); - target = baseToString(target); - return string.slice(position, position + target.length) == target; - } - - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is given, it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options={}] The options object. - * @param {RegExp} [options.escape=_.templateSettings.escape] - * The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] - * The "evaluate" delimiter. - * @param {Object} [options.imports=_.templateSettings.imports] - * An object to import into the template as free variables. - * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] - * The "interpolate" delimiter. - * @param {string} [options.sourceURL='lodash.templateSources[n]'] - * The sourceURL of the compiled template. - * @param {string} [options.variable='obj'] - * The data object variable name. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the compiled template function. - * @example - * - * // Use the "interpolate" delimiter to create a compiled template. - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // Use the HTML "escape" delimiter to escape data property values. - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '\n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -, -" \n" -"
\n" -"
\n" -" \n" -" \n" -"
\n" -"
\n" -"
\n" -"
Generated with nonius
\n" -" \n" -" \n" -"\n" - }; - static std::string const the_template = []() -> std::string { - std::string s; - for(auto part : template_parts) { - s += part; - } - return s; - }(); - return the_template; - } - - std::string description() override { - return "outputs an HTML file with a single interactive chart of all benchmarks"; - } - - void do_configure(configuration& cfg) override { - cfg.no_analysis = false; - title = cfg.title; - n_samples = cfg.samples; - verbose = cfg.verbose; - logarithmic = cfg.params.run && cfg.params.run->op == "*"; - run_param = cfg.params.run ? cfg.params.run->name : ""; - } - - void do_warmup_start() override { - if(verbose) progress_stream() << "warming up\n"; - } - void do_estimate_clock_resolution_start() override { - if(verbose) progress_stream() << "estimating clock resolution\n"; - } - void do_estimate_clock_cost_start() override { - if(verbose) progress_stream() << "estimating cost of a clock call\n"; - } - - void do_params_start(parameters const& params) override { - if(verbose) progress_stream() << "\n\nnew parameter round\n" << params; - runs.emplace_back(); - runs.back().params = params; - } - void do_benchmark_start(std::string const& name) override { - if(verbose) progress_stream() << "\nbenchmarking " << name << "\n"; - runs.back().data.push_back({name, {}, {}}); - } - - void do_measurement_start(execution_plan plan) override { - progress_stream() << std::setprecision(7); - progress_stream().unsetf(std::ios::floatfield); - if(verbose) progress_stream() << "collecting " << n_samples << " samples, " << plan.iterations_per_sample << " iterations each, in estimated " << detail::pretty_duration(plan.estimated_duration) << "\n"; - } - void do_measurement_complete(std::vector const& samples) override { - runs.back().data.back().samples = samples; - } - void do_analysis_complete(sample_analysis const& analysis) override { - runs.back().data.back().analysis = analysis; - } - void do_benchmark_failure(std::exception_ptr) override { - error_stream() << runs.back().data.back().name << " failed to run successfully\n"; - } - - void do_suite_complete() override { - if(verbose) progress_stream() << "\ngenerating HTML report\n"; - - auto&& templ = template_string(); - auto magnitude = ideal_magnitude(); - - cpptempl::data_map map; - map["title"] = escape(title); - map["units"] = detail::units_for_magnitude(magnitude); - map["logarithmic"] = logarithmic; - map["runparam"] = run_param; - for (auto&& r : runs) { - cpptempl::data_map run_item; - cpptempl::data_list params; - for (auto&& p : r.params) { - cpptempl::data_map item; - item["name"] = p.first; - item["value"] = p.second; - params.push_back(item); - } - run_item["params"] = cpptempl::make_data(params); - for(auto&& d : r.data) { - cpptempl::data_map item; - item["name"] = escape(d.name); - cpptempl::data_map data; - if (!d.samples.empty()) { - data["mean"] = truncate(d.analysis.mean.point.count() * magnitude); - data["stddev"] = truncate(d.analysis.standard_deviation.point.count() * magnitude); - for(auto e : d.samples) - data["samples"].push_back(truncate(e.count() * magnitude)); - } - item["data"] = data; - run_item["benchmarks"].push_back(item); - } - map["runs"].push_back(run_item); - } - - cpptempl::parse(report_stream(), templ, map); - report_stream() << std::flush; - if(verbose) { - progress_stream() << "\n\nresult summary (" - << detail::units_for_magnitude(magnitude) - << ")\n"; - for (auto&& r : runs) { - for (auto&& p : r.params) - progress_stream() << "\n " << p.first << " = " << p.second; - progress_stream() << "\n"; - for(auto&& d : r.data) { - progress_stream() << " " << d.name << "\t " - << truncate(d.analysis.mean.point.count() * magnitude) << "\t " - << truncate(d.analysis.standard_deviation.point.count() * magnitude) - << "\n"; - } - } - progress_stream() << "\ndone\n"; - progress_stream() << std::flush; - } - } - - static double truncate(double x) { - return std::trunc(x * 1000.) / 1000.; - } - - double ideal_magnitude() const { - std::vector mins; - mins.reserve(runs.size() * runs.front().data.size()); - for (auto&& r : runs) { - for(auto&& d : r.data) { - if (d.samples.begin() != d.samples.end()) - mins.push_back(*std::min_element(d.samples.begin(), d.samples.end())); - } - } - auto min = *std::min_element(mins.begin(), mins.end()); - return detail::get_magnitude(min); - } - - static std::string escape(std::string const& source) { - static const std::unordered_map escapes { - { '\'', "'" }, - { '"', """ }, - { '<', "<" }, - { '>', ">" }, - { '&', "&" }, - { '\\', "\\\\" }, - }; - return detail::escape(source, escapes); - } - - struct result_t { - std::string name; - std::vector samples; - sample_analysis analysis; - }; - - struct run_t { - parameters params; - std::vector data; - }; - - int n_samples; - bool verbose; - std::string title; - bool logarithmic; - std::string run_param; - std::vector runs; - }; - - NONIUS_REPORTER("html", html_reporter); -} // namespace nonius - -#endif // NONIUS_DISABLE_HTML_REPORTER -#endif // NONIUS_DISABLE_EXTRA_REPORTERS - -#endif // NONIUS_HPP -// #included from: main.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see - -// Executable building kit - -#define NONIUS_MAIN_HPP - -// #included from: detail/argparse.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see - -// Command-line argument parsing - -#define NONIUS_ARGPARSE_HPP - -// #included from: detail/mismatch.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see - -// mismatch algorithm - -#define NONIUS_DETAIL_MISMATCH_HPP - -#include - -namespace nonius { - namespace detail { - template - std::pair mismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p) { - while(first1 != last1 && first2 != last2 && p(*first1, *first2)) { - ++first1, ++first2; - } - return std::make_pair(first1, first2); - } - } // namespace detail -} // namespace nonius - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace nonius { - namespace detail { - struct option { - bool matches_short(std::string const& s) const { - return s == ("-" + short_form); - } - std::tuple long_separator(std::string const& s) const { - auto l = "--" + long_form; - auto its = detail::mismatch(s.begin(), s.end(), l.begin(), l.end(), [](char a, char b) { return a == b; }); - return std::make_tuple(its.second == l.end(), its.first); - } - bool matches_long(std::string const& s) const { - return std::get<0>(long_separator(s)); - } - bool matches_long(std::string const& s, std::string& argument) const { - bool match; std::string::const_iterator it; - std::tie(match, it) = long_separator(s); - if(match && it != s.end()) { - if(*it == '=') argument.assign(it+1, s.end()); - else return false; - } - return match; - } - - option(std::string long_form, std::string short_form, std::string description, std::string argument = std::string(), bool multiple = false) - : long_form(std::move(long_form)), short_form(std::move(short_form)), description(std::move(description)), argument(std::move(argument)), multiple(multiple) {} - - std::string long_form; - std::string short_form; - std::string description; - std::string argument; - bool multiple; - }; - - using option_set = std::vector