├── .gitignore ├── Chapter01 ├── compare.cpp ├── compile_commands.json ├── functionalSum.cpp ├── immutability.cpp ├── join.cpp ├── loop.cpp └── makefile ├── Chapter02 ├── compile_commands.json ├── incrementAll.cpp ├── makefile ├── number.cpp ├── pureFunction.cpp ├── sort.cpp └── staticAccess.cpp ├── Chapter03 ├── add.cpp ├── compile_commands.json ├── immutabilityPassByReference.cpp ├── immutabilityPassByValue.cpp ├── immutabilityPointers.cpp ├── immutableCapture.cpp ├── lambdaIO.cpp ├── lambdasAndClasses.cpp └── makefile ├── Chapter04 ├── basicFunctionalComposition.cpp ├── compile_commands.json ├── composeFunctions.cpp ├── decomposeMultipleArguments.cpp ├── doctest.h └── makefile ├── Chapter05 ├── basicCurrying.cpp ├── basicPartialApplication.cpp ├── compile_commands.json ├── doctest.h ├── makefile └── removeDuplication.cpp ├── Chapter06 ├── compile_commands.json ├── doctest.h ├── makefile ├── ticTacToeResult.cpp └── typicalTransformations.cpp ├── Chapter07 ├── compile_commands.json ├── doctest.h ├── hiddenLoop.cpp ├── makefile └── ticTacToeResult.cpp ├── Chapter08 ├── compile_commands.json ├── doctest.h ├── fromClassToFunctions.cpp ├── makefile ├── ticTacToeResult.cpp └── ticTacToeResultWithClasses.cpp ├── Chapter09 ├── compile_commands.json ├── doctest.h ├── makefile ├── pokerHands.cpp └── testPureFunctions.cpp ├── Chapter10 ├── asynchronousExecution.cpp ├── compile_commands.json ├── doctest.h ├── immer-0.5.0 │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.rst │ ├── benchmark │ │ ├── CMakeLists.txt │ │ ├── config.hpp │ │ ├── extra │ │ │ └── refcounting.cpp │ │ ├── set │ │ │ ├── access.hpp │ │ │ ├── access.ipp │ │ │ ├── insert.hpp │ │ │ ├── insert.ipp │ │ │ ├── iter.hpp │ │ │ ├── iter.ipp │ │ │ ├── string-box │ │ │ │ ├── access.cpp │ │ │ │ ├── generator.ipp │ │ │ │ ├── insert.cpp │ │ │ │ └── iter.cpp │ │ │ ├── string-long │ │ │ │ ├── access.cpp │ │ │ │ ├── generator.ipp │ │ │ │ ├── insert.cpp │ │ │ │ └── iter.cpp │ │ │ ├── string-short │ │ │ │ ├── access.cpp │ │ │ │ ├── generator.ipp │ │ │ │ ├── insert.cpp │ │ │ │ └── iter.cpp │ │ │ └── unsigned │ │ │ │ ├── access.cpp │ │ │ │ ├── generator.ipp │ │ │ │ ├── insert.cpp │ │ │ │ └── iter.cpp │ │ └── vector │ │ │ ├── access.hpp │ │ │ ├── assoc.hpp │ │ │ ├── branching │ │ │ ├── access.ipp │ │ │ ├── assoc.ipp │ │ │ ├── basic │ │ │ │ ├── access.cpp │ │ │ │ ├── assoc.cpp │ │ │ │ ├── concat.cpp │ │ │ │ └── push.cpp │ │ │ ├── concat.ipp │ │ │ ├── gc │ │ │ │ ├── access.cpp │ │ │ │ ├── assoc.cpp │ │ │ │ ├── concat.cpp │ │ │ │ └── push.cpp │ │ │ ├── push.ipp │ │ │ ├── safe │ │ │ │ ├── access.cpp │ │ │ │ ├── assoc.cpp │ │ │ │ ├── concat.cpp │ │ │ │ └── push.cpp │ │ │ └── unsafe │ │ │ │ ├── access.cpp │ │ │ │ ├── assoc.cpp │ │ │ │ ├── concat.cpp │ │ │ │ └── push.cpp │ │ │ ├── common.hpp │ │ │ ├── concat.hpp │ │ │ ├── drop.hpp │ │ │ ├── misc │ │ │ ├── access.cpp │ │ │ ├── assoc.cpp │ │ │ ├── concat.cpp │ │ │ ├── drop.cpp │ │ │ ├── push-front.cpp │ │ │ ├── push.cpp │ │ │ └── take.cpp │ │ │ ├── paper │ │ │ ├── access.cpp │ │ │ ├── assoc-random.cpp │ │ │ ├── assoc.cpp │ │ │ ├── concat.cpp │ │ │ └── push.cpp │ │ │ ├── push.hpp │ │ │ ├── push_front.hpp │ │ │ └── take.hpp │ ├── cmake │ │ ├── FindBoehmGC.cmake │ │ ├── FindGuile.cmake │ │ ├── FindRRB.cmake │ │ └── ImmerUtils.cmake │ ├── codecov.yml │ ├── default.nix │ ├── doc │ │ ├── CMakeLists.txt │ │ ├── Makefile │ │ ├── _static │ │ │ ├── logo-black.svg │ │ │ ├── logo-front.svg │ │ │ ├── logo.svg │ │ │ ├── patreon.svg │ │ │ └── sinusoidal-badge.svg │ │ ├── algorithms.rst │ │ ├── conf.py │ │ ├── containers.rst │ │ ├── doxygen.config │ │ ├── guile.rst │ │ ├── implementation.rst │ │ ├── index.rst │ │ ├── introduction.rst │ │ ├── memory.rst │ │ ├── python.rst │ │ ├── requirements.txt │ │ ├── sphinx-html-hack.bash │ │ └── transients.rst │ ├── example │ │ ├── CMakeLists.txt │ │ ├── array │ │ │ └── array.cpp │ │ ├── box │ │ │ └── box.cpp │ │ ├── flex-vector │ │ │ └── flex-vector.cpp │ │ ├── map │ │ │ └── intro.cpp │ │ ├── set │ │ │ └── intro.cpp │ │ └── vector │ │ │ ├── fizzbuzz.cpp │ │ │ ├── gc.cpp │ │ │ ├── intro.cpp │ │ │ ├── iota-move.cpp │ │ │ ├── iota-slow.cpp │ │ │ ├── iota-transient-std.cpp │ │ │ ├── iota-transient.cpp │ │ │ ├── move.cpp │ │ │ └── vector.cpp │ ├── extra │ │ ├── fuzzer │ │ │ ├── CMakeLists.txt │ │ │ ├── flex-vector-gc.cpp │ │ │ ├── flex-vector.cpp │ │ │ ├── fuzzer_input.hpp │ │ │ ├── vector-gc.cpp │ │ │ └── vector.cpp │ │ ├── guile │ │ │ ├── CMakeLists.txt │ │ │ ├── README.rst │ │ │ ├── benchmark.scm │ │ │ ├── example.scm │ │ │ ├── immer.scm.in │ │ │ ├── scm │ │ │ │ ├── detail │ │ │ │ │ ├── convert.hpp │ │ │ │ │ ├── define.hpp │ │ │ │ │ ├── finalizer_wrapper.hpp │ │ │ │ │ ├── function_args.hpp │ │ │ │ │ ├── invoke.hpp │ │ │ │ │ ├── pack.hpp │ │ │ │ │ ├── subr_wrapper.hpp │ │ │ │ │ └── util.hpp │ │ │ │ ├── group.hpp │ │ │ │ ├── list.hpp │ │ │ │ ├── scm.hpp │ │ │ │ ├── type.hpp │ │ │ │ └── val.hpp │ │ │ └── src │ │ │ │ └── immer.cpp │ │ ├── js │ │ │ ├── immer.cpp │ │ │ ├── index.js │ │ │ ├── index.tpl.html │ │ │ ├── lib │ │ │ │ ├── benchmark.js │ │ │ │ ├── immutable.min.js │ │ │ │ ├── lodash.js │ │ │ │ ├── mori.js │ │ │ │ └── platform.js │ │ │ └── makefile │ │ └── python │ │ │ ├── CMakeLists.txt │ │ │ ├── README.rst │ │ │ ├── benchmark │ │ │ └── test_benchmarks.py │ │ │ ├── example.py │ │ │ ├── immer │ │ │ └── __init__.py │ │ │ └── src │ │ │ ├── immer-boost.cpp │ │ │ ├── immer-pybind.cpp │ │ │ └── immer-raw.cpp │ ├── immer │ │ ├── algorithm.hpp │ │ ├── array.hpp │ │ ├── array_transient.hpp │ │ ├── box.hpp │ │ ├── config.hpp │ │ ├── detail │ │ │ ├── arrays │ │ │ │ ├── no_capacity.hpp │ │ │ │ ├── node.hpp │ │ │ │ └── with_capacity.hpp │ │ │ ├── combine_standard_layout.hpp │ │ │ ├── hamts │ │ │ │ ├── bits.hpp │ │ │ │ ├── champ.hpp │ │ │ │ ├── champ_iterator.hpp │ │ │ │ └── node.hpp │ │ │ ├── iterator_facade.hpp │ │ │ ├── rbts │ │ │ │ ├── bits.hpp │ │ │ │ ├── node.hpp │ │ │ │ ├── operations.hpp │ │ │ │ ├── position.hpp │ │ │ │ ├── rbtree.hpp │ │ │ │ ├── rbtree_iterator.hpp │ │ │ │ ├── rrbtree.hpp │ │ │ │ ├── rrbtree_iterator.hpp │ │ │ │ └── visitor.hpp │ │ │ ├── ref_count_base.hpp │ │ │ ├── type_traits.hpp │ │ │ └── util.hpp │ │ ├── experimental │ │ │ ├── detail │ │ │ │ └── dvektor_impl.hpp │ │ │ └── dvektor.hpp │ │ ├── flex_vector.hpp │ │ ├── flex_vector_transient.hpp │ │ ├── heap │ │ │ ├── cpp_heap.hpp │ │ │ ├── debug_size_heap.hpp │ │ │ ├── free_list_heap.hpp │ │ │ ├── free_list_node.hpp │ │ │ ├── gc_heap.hpp │ │ │ ├── heap_policy.hpp │ │ │ ├── identity_heap.hpp │ │ │ ├── malloc_heap.hpp │ │ │ ├── split_heap.hpp │ │ │ ├── tags.hpp │ │ │ ├── thread_local_free_list_heap.hpp │ │ │ ├── unsafe_free_list_heap.hpp │ │ │ └── with_data.hpp │ │ ├── map.hpp │ │ ├── map_transient.hpp │ │ ├── memory_policy.hpp │ │ ├── refcount │ │ │ ├── enable_intrusive_ptr.hpp │ │ │ ├── no_refcount_policy.hpp │ │ │ ├── refcount_policy.hpp │ │ │ └── unsafe_refcount_policy.hpp │ │ ├── set.hpp │ │ ├── set_transient.hpp │ │ ├── transience │ │ │ ├── gc_transience_policy.hpp │ │ │ └── no_transience_policy.hpp │ │ ├── vector.hpp │ │ └── vector_transient.hpp │ ├── nix │ │ ├── benchmarks.nix │ │ └── docs.nix │ ├── setup.py │ ├── shell.nix │ ├── test │ │ ├── CMakeLists.txt │ │ ├── array │ │ │ ├── default.cpp │ │ │ └── gc.cpp │ │ ├── array_transient │ │ │ ├── default.cpp │ │ │ └── gc.cpp │ │ ├── box │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ ├── generic.ipp │ │ │ ├── recursive.cpp │ │ │ └── vector-of-boxes-transient.cpp │ │ ├── dada.hpp │ │ ├── detail │ │ │ └── type_traits.cpp │ │ ├── experimental │ │ │ └── dvektor.cpp │ │ ├── flex_vector │ │ │ ├── B3-BL0.cpp │ │ │ ├── B3-BL3.cpp │ │ │ ├── default.cpp │ │ │ ├── fuzzed-0.cpp │ │ │ ├── fuzzed-1.cpp │ │ │ ├── fuzzed-2.cpp │ │ │ ├── fuzzed-3.cpp │ │ │ ├── fuzzed-4.cpp │ │ │ ├── gc.cpp │ │ │ ├── generic.ipp │ │ │ ├── issue-45.cpp │ │ │ ├── issue-47.cpp │ │ │ ├── regular-B3-BL3.cpp │ │ │ └── regular-default.cpp │ │ ├── flex_vector_transient │ │ │ ├── B3-BL0.cpp │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ ├── generic.ipp │ │ │ ├── regular-default.cpp │ │ │ └── regular-gc.cpp │ │ ├── map │ │ │ ├── B3.cpp │ │ │ ├── B6.cpp │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ ├── generic.ipp │ │ │ └── issue-56.cpp │ │ ├── memory │ │ │ ├── heaps.cpp │ │ │ └── refcounts.cpp │ │ ├── set │ │ │ ├── B3.cpp │ │ │ ├── B6.cpp │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ └── generic.ipp │ │ ├── transient_tester.hpp │ │ ├── util.hpp │ │ ├── vector │ │ │ ├── B3-BL0.cpp │ │ │ ├── B3-BL2.cpp │ │ │ ├── B3-BL3.cpp │ │ │ ├── B3-BL4.cpp │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ ├── generic.ipp │ │ │ ├── issue-16.cpp │ │ │ └── issue-46.cpp │ │ └── vector_transient │ │ │ ├── B3-BL0.cpp │ │ │ ├── default.cpp │ │ │ ├── gc.cpp │ │ │ └── generic.ipp │ └── tools │ │ ├── bin2c.c │ │ ├── clojure │ │ ├── README.md │ │ ├── project.clj │ │ └── src │ │ │ └── immer_benchmark.clj │ │ ├── docker │ │ └── icfp17 │ │ │ └── Dockerfile │ │ ├── include │ │ ├── catch.hpp │ │ ├── doctest.h │ │ ├── nonius.h++ │ │ └── prettyprint.hpp │ │ ├── licensing-00-add-gpl3.bash │ │ ├── licensing-01-from-gpl3-to-lgpl3.bash │ │ ├── licensing-02-from-lgpl3-to-boost.bash │ │ ├── reproduce-paper-results.bash │ │ ├── scala │ │ ├── README.md │ │ ├── build.sbt │ │ ├── src │ │ │ └── test │ │ │ │ └── scala │ │ │ │ └── org │ │ │ │ └── immer │ │ │ │ └── benchmarks.scala │ │ └── version.sbt │ │ ├── travis │ │ ├── ssh-key.enc │ │ └── ssh-key.pub │ │ └── with-tee.bash ├── immutableDataStructures.cpp ├── makefile ├── memoization.cpp ├── memoryOptimization.cpp ├── parallelExecution.cpp ├── reactive.cpp ├── runWithMemoryConsumptionMonitoring ├── runWithThreadMonitoring └── tailRecursion.cpp ├── Chapter11 ├── compile_commands.json ├── doctest.h ├── exampleBasedTests.cpp ├── makefile └── propertyBasedTests.cpp ├── Chapter12 ├── Employees.csv ├── autoincrement.cpp ├── compile_commands.json ├── computeSalaries.cpp ├── computeSalariesRefactor │ ├── Employees.csv │ ├── compile_commands.json │ ├── computeSalaries.cpp │ ├── computeSalaries.h │ ├── computeSalariesTest │ ├── computeSalariesTest.cpp │ ├── doctest.h │ └── makefile ├── dependencyinjection.cpp ├── doctest.h ├── makefile ├── maybe.cpp ├── numbers.txt ├── state.cpp └── strategy.cpp ├── Chapter13 ├── compile_commands.json ├── doctest.h ├── makefile └── twitter.cpp ├── Chapter14 ├── compile_commands.json ├── doctest.h ├── include │ ├── meta │ │ ├── meta.hpp │ │ └── meta_fwd.hpp │ ├── module.modulemap │ └── range │ │ └── v3 │ │ ├── action.hpp │ │ ├── action │ │ ├── action.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── concepts.hpp │ │ ├── drop.hpp │ │ ├── drop_while.hpp │ │ ├── erase.hpp │ │ ├── insert.hpp │ │ ├── join.hpp │ │ ├── push_back.hpp │ │ ├── push_front.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── reverse.hpp │ │ ├── shuffle.hpp │ │ ├── slice.hpp │ │ ├── sort.hpp │ │ ├── split.hpp │ │ ├── stable_sort.hpp │ │ ├── stride.hpp │ │ ├── take.hpp │ │ ├── take_while.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ └── unstable_remove_if.hpp │ │ ├── algorithm.hpp │ │ ├── algorithm │ │ ├── adjacent_find.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all_of.hpp │ │ ├── any_of.hpp │ │ ├── aux_ │ │ │ ├── equal_range_n.hpp │ │ │ ├── lower_bound_n.hpp │ │ │ ├── merge_n.hpp │ │ │ ├── merge_n_with_buffer.hpp │ │ │ ├── partition_point_n.hpp │ │ │ ├── sort_n_with_buffer.hpp │ │ │ └── upper_bound_n.hpp │ │ ├── binary_search.hpp │ │ ├── copy.hpp │ │ ├── copy_backward.hpp │ │ ├── copy_if.hpp │ │ ├── copy_n.hpp │ │ ├── count.hpp │ │ ├── count_if.hpp │ │ ├── equal.hpp │ │ ├── equal_range.hpp │ │ ├── fill.hpp │ │ ├── fill_n.hpp │ │ ├── find.hpp │ │ ├── find_end.hpp │ │ ├── find_first_of.hpp │ │ ├── find_if.hpp │ │ ├── find_if_not.hpp │ │ ├── for_each.hpp │ │ ├── for_each_n.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── heap_algorithm.hpp │ │ ├── inplace_merge.hpp │ │ ├── is_partitioned.hpp │ │ ├── is_sorted.hpp │ │ ├── is_sorted_until.hpp │ │ ├── lexicographical_compare.hpp │ │ ├── lower_bound.hpp │ │ ├── max.hpp │ │ ├── max_element.hpp │ │ ├── merge.hpp │ │ ├── min.hpp │ │ ├── min_element.hpp │ │ ├── minmax.hpp │ │ ├── minmax_element.hpp │ │ ├── mismatch.hpp │ │ ├── move.hpp │ │ ├── move_backward.hpp │ │ ├── none_of.hpp │ │ ├── nth_element.hpp │ │ ├── partial_sort.hpp │ │ ├── partial_sort_copy.hpp │ │ ├── partition.hpp │ │ ├── partition_copy.hpp │ │ ├── partition_point.hpp │ │ ├── permutation.hpp │ │ ├── remove.hpp │ │ ├── remove_copy.hpp │ │ ├── remove_copy_if.hpp │ │ ├── remove_if.hpp │ │ ├── replace.hpp │ │ ├── replace_copy.hpp │ │ ├── replace_copy_if.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── reverse_copy.hpp │ │ ├── rotate.hpp │ │ ├── rotate_copy.hpp │ │ ├── sample.hpp │ │ ├── search.hpp │ │ ├── search_n.hpp │ │ ├── set_algorithm.hpp │ │ ├── shuffle.hpp │ │ ├── sort.hpp │ │ ├── stable_partition.hpp │ │ ├── stable_sort.hpp │ │ ├── swap_ranges.hpp │ │ ├── tagspec.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ ├── unique_copy.hpp │ │ ├── unstable_remove_if.hpp │ │ └── upper_bound.hpp │ │ ├── all.hpp │ │ ├── at.hpp │ │ ├── back.hpp │ │ ├── begin_end.hpp │ │ ├── core.hpp │ │ ├── data.hpp │ │ ├── detail │ │ ├── adl_get.hpp │ │ ├── config.hpp │ │ ├── satisfy_boost_range.hpp │ │ └── variant.hpp │ │ ├── distance.hpp │ │ ├── empty.hpp │ │ ├── experimental │ │ ├── utility │ │ │ └── generator.hpp │ │ └── view │ │ │ └── shared.hpp │ │ ├── front.hpp │ │ ├── getlines.hpp │ │ ├── index.hpp │ │ ├── istream_range.hpp │ │ ├── iterator_range.hpp │ │ ├── numeric.hpp │ │ ├── numeric │ │ ├── accumulate.hpp │ │ ├── adjacent_difference.hpp │ │ ├── inner_product.hpp │ │ ├── iota.hpp │ │ └── partial_sum.hpp │ │ ├── range_access.hpp │ │ ├── range_concepts.hpp │ │ ├── range_for.hpp │ │ ├── range_fwd.hpp │ │ ├── range_traits.hpp │ │ ├── size.hpp │ │ ├── span.hpp │ │ ├── to_container.hpp │ │ ├── utility │ │ ├── any.hpp │ │ ├── associated_types.hpp │ │ ├── basic_iterator.hpp │ │ ├── box.hpp │ │ ├── common_iterator.hpp │ │ ├── common_tuple.hpp │ │ ├── common_type.hpp │ │ ├── compressed_pair.hpp │ │ ├── concepts.hpp │ │ ├── copy.hpp │ │ ├── counted_iterator.hpp │ │ ├── dangling.hpp │ │ ├── functional.hpp │ │ ├── get.hpp │ │ ├── infinity.hpp │ │ ├── invoke.hpp │ │ ├── iterator.hpp │ │ ├── iterator_concepts.hpp │ │ ├── iterator_traits.hpp │ │ ├── memory.hpp │ │ ├── move.hpp │ │ ├── nullptr_v.hpp │ │ ├── optional.hpp │ │ ├── polymorphic_cast.hpp │ │ ├── random.hpp │ │ ├── scope_exit.hpp │ │ ├── semiregular.hpp │ │ ├── static_const.hpp │ │ ├── swap.hpp │ │ ├── tagged_pair.hpp │ │ ├── tagged_tuple.hpp │ │ ├── tuple_algorithm.hpp │ │ ├── unreachable.hpp │ │ └── variant.hpp │ │ ├── version.hpp │ │ ├── view.hpp │ │ ├── view │ │ ├── addressof.hpp │ │ ├── adjacent_filter.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all.hpp │ │ ├── any_view.hpp │ │ ├── bounded.hpp │ │ ├── c_str.hpp │ │ ├── cartesian_product.hpp │ │ ├── chunk.hpp │ │ ├── concat.hpp │ │ ├── const.hpp │ │ ├── counted.hpp │ │ ├── cycle.hpp │ │ ├── delimit.hpp │ │ ├── drop.hpp │ │ ├── drop_exactly.hpp │ │ ├── drop_while.hpp │ │ ├── empty.hpp │ │ ├── enumerate.hpp │ │ ├── exclusive_scan.hpp │ │ ├── filter.hpp │ │ ├── for_each.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── group_by.hpp │ │ ├── indices.hpp │ │ ├── indirect.hpp │ │ ├── intersperse.hpp │ │ ├── iota.hpp │ │ ├── join.hpp │ │ ├── linear_distribute.hpp │ │ ├── map.hpp │ │ ├── move.hpp │ │ ├── partial_sum.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── repeat.hpp │ │ ├── repeat_n.hpp │ │ ├── replace.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── sample.hpp │ │ ├── set_algorithm.hpp │ │ ├── single.hpp │ │ ├── slice.hpp │ │ ├── sliding.hpp │ │ ├── split.hpp │ │ ├── stride.hpp │ │ ├── tail.hpp │ │ ├── take.hpp │ │ ├── take_exactly.hpp │ │ ├── take_while.hpp │ │ ├── tokenize.hpp │ │ ├── transform.hpp │ │ ├── unbounded.hpp │ │ ├── unique.hpp │ │ ├── view.hpp │ │ ├── zip.hpp │ │ └── zip_with.hpp │ │ ├── view_adaptor.hpp │ │ ├── view_facade.hpp │ │ └── view_interface.hpp ├── makefile └── ranges.cpp ├── Chapter15 ├── algorithm.cpp ├── compile_commands.json ├── doctest.h ├── functional.cpp ├── include │ ├── meta │ │ ├── meta.hpp │ │ └── meta_fwd.hpp │ ├── module.modulemap │ └── range │ │ └── v3 │ │ ├── action.hpp │ │ ├── action │ │ ├── action.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── concepts.hpp │ │ ├── drop.hpp │ │ ├── drop_while.hpp │ │ ├── erase.hpp │ │ ├── insert.hpp │ │ ├── join.hpp │ │ ├── push_back.hpp │ │ ├── push_front.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── reverse.hpp │ │ ├── shuffle.hpp │ │ ├── slice.hpp │ │ ├── sort.hpp │ │ ├── split.hpp │ │ ├── stable_sort.hpp │ │ ├── stride.hpp │ │ ├── take.hpp │ │ ├── take_while.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ └── unstable_remove_if.hpp │ │ ├── algorithm.hpp │ │ ├── algorithm │ │ ├── adjacent_find.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all_of.hpp │ │ ├── any_of.hpp │ │ ├── aux_ │ │ │ ├── equal_range_n.hpp │ │ │ ├── lower_bound_n.hpp │ │ │ ├── merge_n.hpp │ │ │ ├── merge_n_with_buffer.hpp │ │ │ ├── partition_point_n.hpp │ │ │ ├── sort_n_with_buffer.hpp │ │ │ └── upper_bound_n.hpp │ │ ├── binary_search.hpp │ │ ├── copy.hpp │ │ ├── copy_backward.hpp │ │ ├── copy_if.hpp │ │ ├── copy_n.hpp │ │ ├── count.hpp │ │ ├── count_if.hpp │ │ ├── equal.hpp │ │ ├── equal_range.hpp │ │ ├── fill.hpp │ │ ├── fill_n.hpp │ │ ├── find.hpp │ │ ├── find_end.hpp │ │ ├── find_first_of.hpp │ │ ├── find_if.hpp │ │ ├── find_if_not.hpp │ │ ├── for_each.hpp │ │ ├── for_each_n.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── heap_algorithm.hpp │ │ ├── inplace_merge.hpp │ │ ├── is_partitioned.hpp │ │ ├── is_sorted.hpp │ │ ├── is_sorted_until.hpp │ │ ├── lexicographical_compare.hpp │ │ ├── lower_bound.hpp │ │ ├── max.hpp │ │ ├── max_element.hpp │ │ ├── merge.hpp │ │ ├── min.hpp │ │ ├── min_element.hpp │ │ ├── minmax.hpp │ │ ├── minmax_element.hpp │ │ ├── mismatch.hpp │ │ ├── move.hpp │ │ ├── move_backward.hpp │ │ ├── none_of.hpp │ │ ├── nth_element.hpp │ │ ├── partial_sort.hpp │ │ ├── partial_sort_copy.hpp │ │ ├── partition.hpp │ │ ├── partition_copy.hpp │ │ ├── partition_point.hpp │ │ ├── permutation.hpp │ │ ├── remove.hpp │ │ ├── remove_copy.hpp │ │ ├── remove_copy_if.hpp │ │ ├── remove_if.hpp │ │ ├── replace.hpp │ │ ├── replace_copy.hpp │ │ ├── replace_copy_if.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── reverse_copy.hpp │ │ ├── rotate.hpp │ │ ├── rotate_copy.hpp │ │ ├── sample.hpp │ │ ├── search.hpp │ │ ├── search_n.hpp │ │ ├── set_algorithm.hpp │ │ ├── shuffle.hpp │ │ ├── sort.hpp │ │ ├── stable_partition.hpp │ │ ├── stable_sort.hpp │ │ ├── swap_ranges.hpp │ │ ├── tagspec.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ ├── unique_copy.hpp │ │ ├── unstable_remove_if.hpp │ │ └── upper_bound.hpp │ │ ├── all.hpp │ │ ├── at.hpp │ │ ├── back.hpp │ │ ├── begin_end.hpp │ │ ├── core.hpp │ │ ├── data.hpp │ │ ├── detail │ │ ├── adl_get.hpp │ │ ├── config.hpp │ │ ├── satisfy_boost_range.hpp │ │ └── variant.hpp │ │ ├── distance.hpp │ │ ├── empty.hpp │ │ ├── experimental │ │ ├── utility │ │ │ └── generator.hpp │ │ └── view │ │ │ └── shared.hpp │ │ ├── front.hpp │ │ ├── getlines.hpp │ │ ├── index.hpp │ │ ├── istream_range.hpp │ │ ├── iterator_range.hpp │ │ ├── numeric.hpp │ │ ├── numeric │ │ ├── accumulate.hpp │ │ ├── adjacent_difference.hpp │ │ ├── inner_product.hpp │ │ ├── iota.hpp │ │ └── partial_sum.hpp │ │ ├── range_access.hpp │ │ ├── range_concepts.hpp │ │ ├── range_for.hpp │ │ ├── range_fwd.hpp │ │ ├── range_traits.hpp │ │ ├── size.hpp │ │ ├── span.hpp │ │ ├── to_container.hpp │ │ ├── utility │ │ ├── any.hpp │ │ ├── associated_types.hpp │ │ ├── basic_iterator.hpp │ │ ├── box.hpp │ │ ├── common_iterator.hpp │ │ ├── common_tuple.hpp │ │ ├── common_type.hpp │ │ ├── compressed_pair.hpp │ │ ├── concepts.hpp │ │ ├── copy.hpp │ │ ├── counted_iterator.hpp │ │ ├── dangling.hpp │ │ ├── functional.hpp │ │ ├── get.hpp │ │ ├── infinity.hpp │ │ ├── invoke.hpp │ │ ├── iterator.hpp │ │ ├── iterator_concepts.hpp │ │ ├── iterator_traits.hpp │ │ ├── memory.hpp │ │ ├── move.hpp │ │ ├── nullptr_v.hpp │ │ ├── optional.hpp │ │ ├── polymorphic_cast.hpp │ │ ├── random.hpp │ │ ├── scope_exit.hpp │ │ ├── semiregular.hpp │ │ ├── static_const.hpp │ │ ├── swap.hpp │ │ ├── tagged_pair.hpp │ │ ├── tagged_tuple.hpp │ │ ├── tuple_algorithm.hpp │ │ ├── unreachable.hpp │ │ └── variant.hpp │ │ ├── version.hpp │ │ ├── view.hpp │ │ ├── view │ │ ├── addressof.hpp │ │ ├── adjacent_filter.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all.hpp │ │ ├── any_view.hpp │ │ ├── bounded.hpp │ │ ├── c_str.hpp │ │ ├── cartesian_product.hpp │ │ ├── chunk.hpp │ │ ├── concat.hpp │ │ ├── const.hpp │ │ ├── counted.hpp │ │ ├── cycle.hpp │ │ ├── delimit.hpp │ │ ├── drop.hpp │ │ ├── drop_exactly.hpp │ │ ├── drop_while.hpp │ │ ├── empty.hpp │ │ ├── enumerate.hpp │ │ ├── exclusive_scan.hpp │ │ ├── filter.hpp │ │ ├── for_each.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── group_by.hpp │ │ ├── indices.hpp │ │ ├── indirect.hpp │ │ ├── intersperse.hpp │ │ ├── iota.hpp │ │ ├── join.hpp │ │ ├── linear_distribute.hpp │ │ ├── map.hpp │ │ ├── move.hpp │ │ ├── partial_sum.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── repeat.hpp │ │ ├── repeat_n.hpp │ │ ├── replace.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── sample.hpp │ │ ├── set_algorithm.hpp │ │ ├── single.hpp │ │ ├── slice.hpp │ │ ├── sliding.hpp │ │ ├── split.hpp │ │ ├── stride.hpp │ │ ├── tail.hpp │ │ ├── take.hpp │ │ ├── take_exactly.hpp │ │ ├── take_while.hpp │ │ ├── tokenize.hpp │ │ ├── transform.hpp │ │ ├── unbounded.hpp │ │ ├── unique.hpp │ │ ├── view.hpp │ │ ├── zip.hpp │ │ └── zip_with.hpp │ │ ├── view_adaptor.hpp │ │ ├── view_facade.hpp │ │ └── view_interface.hpp └── makefile ├── Chapter16 ├── compile_commands.json ├── doctest.h ├── functional.cpp ├── functionalComposition.cpp ├── include │ ├── meta │ │ ├── meta.hpp │ │ └── meta_fwd.hpp │ ├── module.modulemap │ └── range │ │ └── v3 │ │ ├── action.hpp │ │ ├── action │ │ ├── action.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── concepts.hpp │ │ ├── drop.hpp │ │ ├── drop_while.hpp │ │ ├── erase.hpp │ │ ├── insert.hpp │ │ ├── join.hpp │ │ ├── push_back.hpp │ │ ├── push_front.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── reverse.hpp │ │ ├── shuffle.hpp │ │ ├── slice.hpp │ │ ├── sort.hpp │ │ ├── split.hpp │ │ ├── stable_sort.hpp │ │ ├── stride.hpp │ │ ├── take.hpp │ │ ├── take_while.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ └── unstable_remove_if.hpp │ │ ├── algorithm.hpp │ │ ├── algorithm │ │ ├── adjacent_find.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all_of.hpp │ │ ├── any_of.hpp │ │ ├── aux_ │ │ │ ├── equal_range_n.hpp │ │ │ ├── lower_bound_n.hpp │ │ │ ├── merge_n.hpp │ │ │ ├── merge_n_with_buffer.hpp │ │ │ ├── partition_point_n.hpp │ │ │ ├── sort_n_with_buffer.hpp │ │ │ └── upper_bound_n.hpp │ │ ├── binary_search.hpp │ │ ├── copy.hpp │ │ ├── copy_backward.hpp │ │ ├── copy_if.hpp │ │ ├── copy_n.hpp │ │ ├── count.hpp │ │ ├── count_if.hpp │ │ ├── equal.hpp │ │ ├── equal_range.hpp │ │ ├── fill.hpp │ │ ├── fill_n.hpp │ │ ├── find.hpp │ │ ├── find_end.hpp │ │ ├── find_first_of.hpp │ │ ├── find_if.hpp │ │ ├── find_if_not.hpp │ │ ├── for_each.hpp │ │ ├── for_each_n.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── heap_algorithm.hpp │ │ ├── inplace_merge.hpp │ │ ├── is_partitioned.hpp │ │ ├── is_sorted.hpp │ │ ├── is_sorted_until.hpp │ │ ├── lexicographical_compare.hpp │ │ ├── lower_bound.hpp │ │ ├── max.hpp │ │ ├── max_element.hpp │ │ ├── merge.hpp │ │ ├── min.hpp │ │ ├── min_element.hpp │ │ ├── minmax.hpp │ │ ├── minmax_element.hpp │ │ ├── mismatch.hpp │ │ ├── move.hpp │ │ ├── move_backward.hpp │ │ ├── none_of.hpp │ │ ├── nth_element.hpp │ │ ├── partial_sort.hpp │ │ ├── partial_sort_copy.hpp │ │ ├── partition.hpp │ │ ├── partition_copy.hpp │ │ ├── partition_point.hpp │ │ ├── permutation.hpp │ │ ├── remove.hpp │ │ ├── remove_copy.hpp │ │ ├── remove_copy_if.hpp │ │ ├── remove_if.hpp │ │ ├── replace.hpp │ │ ├── replace_copy.hpp │ │ ├── replace_copy_if.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── reverse_copy.hpp │ │ ├── rotate.hpp │ │ ├── rotate_copy.hpp │ │ ├── sample.hpp │ │ ├── search.hpp │ │ ├── search_n.hpp │ │ ├── set_algorithm.hpp │ │ ├── shuffle.hpp │ │ ├── sort.hpp │ │ ├── stable_partition.hpp │ │ ├── stable_sort.hpp │ │ ├── swap_ranges.hpp │ │ ├── tagspec.hpp │ │ ├── transform.hpp │ │ ├── unique.hpp │ │ ├── unique_copy.hpp │ │ ├── unstable_remove_if.hpp │ │ └── upper_bound.hpp │ │ ├── all.hpp │ │ ├── at.hpp │ │ ├── back.hpp │ │ ├── begin_end.hpp │ │ ├── core.hpp │ │ ├── data.hpp │ │ ├── detail │ │ ├── adl_get.hpp │ │ ├── config.hpp │ │ ├── satisfy_boost_range.hpp │ │ └── variant.hpp │ │ ├── distance.hpp │ │ ├── empty.hpp │ │ ├── experimental │ │ ├── utility │ │ │ └── generator.hpp │ │ └── view │ │ │ └── shared.hpp │ │ ├── front.hpp │ │ ├── getlines.hpp │ │ ├── index.hpp │ │ ├── istream_range.hpp │ │ ├── iterator_range.hpp │ │ ├── numeric.hpp │ │ ├── numeric │ │ ├── accumulate.hpp │ │ ├── adjacent_difference.hpp │ │ ├── inner_product.hpp │ │ ├── iota.hpp │ │ └── partial_sum.hpp │ │ ├── range_access.hpp │ │ ├── range_concepts.hpp │ │ ├── range_for.hpp │ │ ├── range_fwd.hpp │ │ ├── range_traits.hpp │ │ ├── size.hpp │ │ ├── span.hpp │ │ ├── to_container.hpp │ │ ├── utility │ │ ├── any.hpp │ │ ├── associated_types.hpp │ │ ├── basic_iterator.hpp │ │ ├── box.hpp │ │ ├── common_iterator.hpp │ │ ├── common_tuple.hpp │ │ ├── common_type.hpp │ │ ├── compressed_pair.hpp │ │ ├── concepts.hpp │ │ ├── copy.hpp │ │ ├── counted_iterator.hpp │ │ ├── dangling.hpp │ │ ├── functional.hpp │ │ ├── get.hpp │ │ ├── infinity.hpp │ │ ├── invoke.hpp │ │ ├── iterator.hpp │ │ ├── iterator_concepts.hpp │ │ ├── iterator_traits.hpp │ │ ├── memory.hpp │ │ ├── move.hpp │ │ ├── nullptr_v.hpp │ │ ├── optional.hpp │ │ ├── polymorphic_cast.hpp │ │ ├── random.hpp │ │ ├── scope_exit.hpp │ │ ├── semiregular.hpp │ │ ├── static_const.hpp │ │ ├── swap.hpp │ │ ├── tagged_pair.hpp │ │ ├── tagged_tuple.hpp │ │ ├── tuple_algorithm.hpp │ │ ├── unreachable.hpp │ │ └── variant.hpp │ │ ├── version.hpp │ │ ├── view.hpp │ │ ├── view │ │ ├── addressof.hpp │ │ ├── adjacent_filter.hpp │ │ ├── adjacent_remove_if.hpp │ │ ├── all.hpp │ │ ├── any_view.hpp │ │ ├── bounded.hpp │ │ ├── c_str.hpp │ │ ├── cartesian_product.hpp │ │ ├── chunk.hpp │ │ ├── concat.hpp │ │ ├── const.hpp │ │ ├── counted.hpp │ │ ├── cycle.hpp │ │ ├── delimit.hpp │ │ ├── drop.hpp │ │ ├── drop_exactly.hpp │ │ ├── drop_while.hpp │ │ ├── empty.hpp │ │ ├── enumerate.hpp │ │ ├── exclusive_scan.hpp │ │ ├── filter.hpp │ │ ├── for_each.hpp │ │ ├── generate.hpp │ │ ├── generate_n.hpp │ │ ├── group_by.hpp │ │ ├── indices.hpp │ │ ├── indirect.hpp │ │ ├── intersperse.hpp │ │ ├── iota.hpp │ │ ├── join.hpp │ │ ├── linear_distribute.hpp │ │ ├── map.hpp │ │ ├── move.hpp │ │ ├── partial_sum.hpp │ │ ├── remove.hpp │ │ ├── remove_if.hpp │ │ ├── repeat.hpp │ │ ├── repeat_n.hpp │ │ ├── replace.hpp │ │ ├── replace_if.hpp │ │ ├── reverse.hpp │ │ ├── sample.hpp │ │ ├── set_algorithm.hpp │ │ ├── single.hpp │ │ ├── slice.hpp │ │ ├── sliding.hpp │ │ ├── split.hpp │ │ ├── stride.hpp │ │ ├── tail.hpp │ │ ├── take.hpp │ │ ├── take_exactly.hpp │ │ ├── take_while.hpp │ │ ├── tokenize.hpp │ │ ├── transform.hpp │ │ ├── unbounded.hpp │ │ ├── unique.hpp │ │ ├── view.hpp │ │ ├── zip.hpp │ │ └── zip_with.hpp │ │ ├── view_adaptor.hpp │ │ ├── view_facade.hpp │ │ └── view_interface.hpp ├── lambdas.cpp ├── makefile └── partialApplication.cpp ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | out/ 3 | -------------------------------------------------------------------------------- /Chapter01/compare.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Name{ 8 | Name(){} 9 | Name(const string& providedFirstName, const string& providedLastName): firstName(providedFirstName), lastName(providedLastName){ 10 | } 11 | string firstName; 12 | string lastName; 13 | }; 14 | 15 | bool compareByFirstName(const Name& first, const Name& second){ 16 | return first.firstName < second.firstName; 17 | } 18 | 19 | int main(){ 20 | vector names = {Name("John", "Smith"), Name("Alex", "Bolboaca")}; 21 | 22 | sort(names.begin(), names.end(), compareByFirstName); 23 | 24 | for(auto iterator = names.begin(); iterator != names.end(); ++iterator){ 25 | cout << iterator->firstName 26 | << " " << iterator->lastName << ", "; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Chapter01/immutability.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Add{ 5 | private: 6 | int aMember; 7 | 8 | public: 9 | Add(int initialValue): aMember(initialValue){} 10 | 11 | int getDataMember() const {return aMember;} 12 | 13 | int add(const int& first, const int& second) const{ 14 | return first + second; 15 | } 16 | 17 | int uglyAdd(int& first, int& second){ 18 | first = first + second; 19 | aMember = 40; 20 | return first; 21 | } 22 | }; 23 | 24 | 25 | int main(){ 26 | Add value(42); 27 | 28 | int first = 10; 29 | int second = 20; 30 | 31 | cout << "==== add ===" << endl; 32 | cout << value.add(10, 20) << endl; 33 | cout << value.getDataMember() << endl; 34 | cout << first << endl; 35 | cout << "------------" << endl; 36 | 37 | cout << "==== uglyAdd ===" << endl; 38 | cout << value.uglyAdd(first, second) << endl; 39 | cout << value.getDataMember() << endl; 40 | cout << first << endl; 41 | cout << "------------" << endl; 42 | } 43 | -------------------------------------------------------------------------------- /Chapter01/join.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | vector range(const int count){ 11 | vector aVector(count); 12 | iota(aVector.begin(), aVector.end(), 1); 13 | return aVector; 14 | } 15 | string concatenate(const int element) { 16 | return to_string(element) + ", "; 17 | } 18 | 19 | 20 | int main() { 21 | auto myRange = range(10); 22 | std::stringstream output; 23 | std::transform( 24 | myRange.begin(), 25 | myRange.end(), 26 | ostream_iterator(output), 27 | concatenate 28 | ); 29 | cout << output.str() << endl; 30 | 31 | for(auto iter = myRange.begin(); iter != myRange.end(); ++iter){ 32 | cout << *iter << ", "; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Chapter01/makefile: -------------------------------------------------------------------------------- 1 | all: immutability loop join compare functionalSum 2 | 3 | .outDir: 4 | mkdir -p out 5 | 6 | immutability: .outDir 7 | g++ -std=c++17 immutability.cpp -o out/immutability 8 | ./out/immutability 9 | 10 | loop: .outDir 11 | g++ -std=c++17 loop.cpp -o out/loop 12 | ./out/loop 13 | 14 | join: .outDir 15 | g++ -std=c++17 join.cpp -o out/join 16 | ./out/join 17 | 18 | compare: .outDir 19 | g++ -std=c++17 compare.cpp -o out/compare 20 | ./out/compare 21 | 22 | functionalSum: .outDir 23 | g++ -std=c++17 functionalSum.cpp -o out/functionalSum 24 | ./out/functionalSum 25 | -------------------------------------------------------------------------------- /Chapter02/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-o", 8 | "out/sort", 9 | "sort.cpp" 10 | ], 11 | "directory": "/home/alexb/work/bookCode/chapter2", 12 | "file": "sort.cpp" 13 | } 14 | ] -------------------------------------------------------------------------------- /Chapter02/incrementAll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | void incrementAll(int& first, int& second){ 7 | ++first; 8 | ++second; 9 | } 10 | 11 | const tuple incrementAllPure(const int& first, const int& second){ 12 | return make_tuple(first + 1, second + 1); 13 | } 14 | 15 | int main(){ 16 | int first = 1; 17 | int second = 2; 18 | 19 | incrementAll(first, second); 20 | 21 | cout << "First: " << first << endl; 22 | cout << "Second: " << second << endl; 23 | 24 | 25 | auto results = incrementAllPure(1, 2); 26 | cout << "Incremented pure: " << get<0>(results) << endl; 27 | cout << "Incremented pure: " << get<1>(results) << endl; 28 | } 29 | -------------------------------------------------------------------------------- /Chapter02/makefile: -------------------------------------------------------------------------------- 1 | all: sort incrementAll staticAccess pureFunction number 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | sort: .outputFolder 7 | g++ -std=c++17 sort.cpp -o out/sort 8 | ./out/sort 9 | 10 | incrementAll: .outputFolder 11 | g++ -std=c++17 incrementAll.cpp -o out/incrementAll 12 | ./out/incrementAll 13 | 14 | staticAccess: .outputFolder 15 | g++ -std=c++17 staticAccess.cpp -o out/staticAccess 16 | ./out/staticAccess 17 | 18 | pureFunction: .outputFolder 19 | g++ -std=c++17 pureFunction.cpp -o out/pureFunction 20 | ./out/pureFunction 21 | 22 | number: .outputFolder 23 | g++ -std=c++17 number.cpp -o out/number 24 | ./out/number 25 | -------------------------------------------------------------------------------- /Chapter02/number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Number{ 5 | private: 6 | int initialValue; 7 | 8 | public: 9 | Number(int initialValue) : initialValue(initialValue){} 10 | int initial() const{ return initialValue; } 11 | int addToInitial(const int& first) const{ return first + initialValue; } 12 | }; 13 | 14 | int main(){ 15 | Number number(10); 16 | cout << number.addToInitial(20) << endl; 17 | } 18 | -------------------------------------------------------------------------------- /Chapter02/sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main(){ 8 | vector values = {324, 454, 12, 45, 54564, 32}; 9 | sort(values.begin(), values.end()); 10 | 11 | for(auto it = values.begin(); it 2 | 3 | using namespace std; 4 | 5 | class Number{ 6 | private: 7 | static const int accessCount = 0; 8 | 9 | public: 10 | static int zero(){return 0;} 11 | static int getCount() { return accessCount; } 12 | }; 13 | 14 | 15 | int main(){ 16 | Number::zero(); 17 | cout << Number::getCount() << endl; 18 | } 19 | -------------------------------------------------------------------------------- /Chapter03/immutabilityPassByReference.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | auto increment = [](int& value) { 6 | return ++value; 7 | }; 8 | 9 | auto incrementImmutable = [](const int& value){ 10 | return value + 1; 11 | }; 12 | 13 | int main(){ 14 | int valueToIncrement = 41; 15 | cout << increment(valueToIncrement) << endl;// prints 42 16 | cout << valueToIncrement << endl;// prints 42 17 | 18 | valueToIncrement = 41; 19 | cout << incrementImmutable(valueToIncrement) << endl;// prints 42 20 | cout << valueToIncrement << endl;// prints 42 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/immutabilityPassByValue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | auto increment = [](int value) { 7 | return ++value; 8 | }; 9 | 10 | auto incrementImmutable = [](const int value) { 11 | return value + 1; 12 | }; 13 | 14 | int main(){ 15 | int valueToIncrement = 41; 16 | cout << increment(valueToIncrement) << endl;// prints 42 17 | cout << valueToIncrement << endl;// prints 41 18 | 19 | cout << incrementImmutable(valueToIncrement) << endl;// prints 42 20 | cout << valueToIncrement << endl;// prints 41 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/lambdaIO.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | auto hello = [](){cout << "Hello, world!" << endl;}; 6 | 7 | int main(){ 8 | hello(); 9 | } 10 | -------------------------------------------------------------------------------- /Chapter03/makefile: -------------------------------------------------------------------------------- 1 | all: add immutabilityPassByValue immutabilityPassByReference immutabilityPointers lambdaIO immutableCapture lambdasAndClasses 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | add: .outputFolder 7 | g++ -std=c++17 add.cpp -o out/add 8 | ./out/add 9 | 10 | immutabilityPassByValue: .outputFolder 11 | g++ -std=c++17 immutabilityPassByValue.cpp -o out/immutabilityPassByValue 12 | ./out/immutabilityPassByValue 13 | 14 | immutabilityPassByReference: .outputFolder 15 | g++ -std=c++17 immutabilityPassByReference.cpp -o out/immutabilityPassByReference 16 | ./out/immutabilityPassByReference 17 | 18 | immutabilityPointers: .outputFolder 19 | g++ -std=c++17 immutabilityPointers.cpp -o out/immutabilityPointers 20 | ./out/immutabilityPointers 21 | 22 | lambdaIO: .outputFolder 23 | g++ -std=c++17 lambdaIO.cpp -o out/lambdaIO 24 | ./out/lambdaIO 25 | 26 | immutableCapture: .outputFolder 27 | g++ -std=c++17 immutableCapture.cpp -o out/immutableCapture 28 | ./out/immutableCapture 29 | 30 | lambdasAndClasses: .outputFolder 31 | g++ -std=c++17 lambdasAndClasses.cpp -o out/lambdasAndClasses 32 | ./out/lambdasAndClasses 33 | -------------------------------------------------------------------------------- /Chapter04/basicFunctionalComposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 3 | #include "doctest.h" 4 | 5 | using namespace std; 6 | 7 | auto increment = [](const int value) { return value + 1; }; 8 | 9 | TEST_CASE("Increments value"){ 10 | CHECK_EQ(2, increment(1)); 11 | } 12 | 13 | TEST_CASE("Increments twice"){ 14 | CHECK_EQ(3, increment(increment(1))); 15 | } 16 | 17 | auto incrementTwiceLambda = [](int value){return increment(increment(value));}; 18 | 19 | TEST_CASE("Increments result of addition with lambda"){ 20 | CHECK_EQ(3, incrementTwiceLambda(1)); 21 | } 22 | 23 | auto square = [](int value){ return value * value; }; 24 | 25 | TEST_CASE("Squares the number"){ 26 | CHECK_EQ(4, square(2)); 27 | } 28 | 29 | auto incrementSquareLambda = [](int value) { return increment(square(value));}; 30 | 31 | TEST_CASE("Increments the squared number"){ 32 | CHECK_EQ(5, incrementSquareLambda(2)); 33 | } 34 | 35 | template 36 | auto compose(F f, G g){ 37 | return [=](auto value){return f(g(value));}; 38 | } 39 | 40 | TEST_CASE("Increments twice with composed lambda"){ 41 | auto incrementTwice = compose(increment, increment); 42 | CHECK_EQ(3, incrementTwice(1)); 43 | } 44 | 45 | 46 | TEST_CASE("Increments square with composed lambda"){ 47 | auto incrementSquare = compose(increment, square); 48 | CHECK_EQ(5, incrementSquare(2)); 49 | } 50 | -------------------------------------------------------------------------------- /Chapter04/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-o", 8 | "out/decomposeMultipleArguments", 9 | "decomposeMultipleArguments.cpp" 10 | ], 11 | "directory": "/home/alexb/work/bookCode/chapter4", 12 | "file": "decomposeMultipleArguments.cpp" 13 | }, 14 | { 15 | "arguments": [ 16 | "c++", 17 | "-c", 18 | "-std=c++17", 19 | "-o", 20 | "out/basicFunctionalComposition", 21 | "basicFunctionalComposition.cpp" 22 | ], 23 | "directory": "/home/alexb/work/bookCode/chapter4", 24 | "file": "basicFunctionalComposition.cpp" 25 | }, 26 | { 27 | "arguments": [ 28 | "c++", 29 | "-c", 30 | "-std=c++17", 31 | "-o", 32 | "out/composeFunctions", 33 | "composeFunctions.cpp" 34 | ], 35 | "directory": "/home/alexb/work/bookCode/chapter4", 36 | "file": "composeFunctions.cpp" 37 | } 38 | ] -------------------------------------------------------------------------------- /Chapter04/composeFunctions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 3 | #include "doctest.h" 4 | #include 5 | 6 | using namespace std; 7 | 8 | auto increment = [](const int value) { return value + 1; }; 9 | auto square = [](int value){ return value * value; }; 10 | 11 | auto simpleCompose(function f, function g){ 12 | return [=](auto x){return f(g(x));}; 13 | } 14 | 15 | TEST_CASE("Increments twice with composed lambda"){ 16 | auto incrementTwice = simpleCompose(increment, increment); 17 | CHECK_EQ(3, incrementTwice(1)); 18 | } 19 | 20 | TEST_CASE("Increments square with composed lambda"){ 21 | auto incrementSquare = simpleCompose(increment, square); 22 | CHECK_EQ(5, incrementSquare(2)); 23 | } 24 | 25 | template 26 | auto compose(F f, G g){ 27 | return [=](auto value){return f(g(value));}; 28 | } 29 | 30 | TEST_CASE("Increments twice with generic composed lambda"){ 31 | auto incrementTwice = compose(increment, increment); 32 | CHECK_EQ(3, incrementTwice(1)); 33 | } 34 | 35 | TEST_CASE("Increments square with generic composed lambda"){ 36 | auto incrementSquare = compose(increment, square); 37 | CHECK_EQ(5, incrementSquare(2)); 38 | } 39 | 40 | TEST_CASE("Square the increment"){ 41 | auto squareIncrement = compose(square, increment); 42 | CHECK_EQ(9, squareIncrement(2)); 43 | } 44 | -------------------------------------------------------------------------------- /Chapter04/makefile: -------------------------------------------------------------------------------- 1 | all: basicFunctionalComposition composeFunctions decomposeMultipleArguments 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | basicFunctionalComposition: .outputFolder 7 | g++ -std=c++17 basicFunctionalComposition.cpp -o out/basicFunctionalComposition 8 | ./out/basicFunctionalComposition 9 | 10 | composeFunctions: .outputFolder 11 | g++ -std=c++17 composeFunctions.cpp -o out/composeFunctions 12 | ./out/composeFunctions 13 | 14 | decomposeMultipleArguments: .outputFolder 15 | g++ -std=c++17 decomposeMultipleArguments.cpp -o out/decomposeMultipleArguments 16 | ./out/decomposeMultipleArguments 17 | -------------------------------------------------------------------------------- /Chapter05/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-o", 8 | "out/basicCurrying", 9 | "basicCurrying.cpp" 10 | ], 11 | "directory": "/home/alexb/work/bookCode/chapter5", 12 | "file": "basicCurrying.cpp" 13 | }, 14 | { 15 | "arguments": [ 16 | "c++", 17 | "-c", 18 | "-std=c++17", 19 | "-o", 20 | "out/basicPartialApplication", 21 | "basicPartialApplication.cpp" 22 | ], 23 | "directory": "/home/alexb/work/bookCode/chapter5", 24 | "file": "basicPartialApplication.cpp" 25 | }, 26 | { 27 | "arguments": [ 28 | "c++", 29 | "-c", 30 | "-std=c++17", 31 | "-o", 32 | "out/removeDuplication", 33 | "removeDuplication.cpp" 34 | ], 35 | "directory": "/home/alexb/work/bookCode/chapter5", 36 | "file": "removeDuplication.cpp" 37 | } 38 | ] -------------------------------------------------------------------------------- /Chapter05/makefile: -------------------------------------------------------------------------------- 1 | all: basicPartialApplication basicCurrying removeDuplication 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | basicPartialApplication: .outputFolder 7 | g++ -std=c++17 basicPartialApplication.cpp -o out/basicPartialApplication 8 | ./out/basicPartialApplication 9 | 10 | basicCurrying: .outputFolder 11 | g++ -std=c++17 basicCurrying.cpp -o out/basicCurrying 12 | ./out/basicCurrying 13 | 14 | removeDuplication: .outputFolder 15 | g++ -std=c++17 removeDuplication.cpp -o out/removeDuplication 16 | ./out/removeDuplication 17 | -------------------------------------------------------------------------------- /Chapter05/removeDuplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 4 | #include "doctest.h" 5 | 6 | using namespace std; 7 | using namespace std::placeholders; 8 | 9 | auto addWrapped = [](const auto first, const auto second, const auto wrapAt) { return (first + second) % wrapAt; }; 10 | 11 | auto add = bind(addWrapped, _1, _2, 20); 12 | 13 | TEST_CASE("Adds values"){ 14 | CHECK_EQ(7, add(10, 17)); 15 | } 16 | 17 | template 18 | auto increment = bind(add, _1, one); 19 | 20 | TEST_CASE("Increments"){ 21 | CHECK_EQ(1, increment(20)); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter06/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/ticTacToeResult", 12 | "ticTacToeResult.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter6", 15 | "file": "ticTacToeResult.cpp" 16 | }, 17 | { 18 | "arguments": [ 19 | "c++", 20 | "-c", 21 | "-std=c++17", 22 | "-o", 23 | "out/typicalTransformations", 24 | "typicalTransformations.cpp" 25 | ], 26 | "directory": "/home/alexb/work/bookCode/chapter6", 27 | "file": "typicalTransformations.cpp" 28 | } 29 | ] -------------------------------------------------------------------------------- /Chapter06/makefile: -------------------------------------------------------------------------------- 1 | all: ticTacToeResult typicalTransformations 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | ticTacToeResult: .outputFolder 7 | g++ -std=c++17 ticTacToeResult.cpp -Wall -Wextra -Werror -o out/ticTacToeResult 8 | ./out/ticTacToeResult 9 | 10 | typicalTransformations: .outputFolder 11 | g++ -std=c++17 typicalTransformations.cpp -o out/typicalTransformations 12 | ./out/typicalTransformations 13 | 14 | -------------------------------------------------------------------------------- /Chapter07/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/ticTacToeResult", 12 | "ticTacToeResult.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter7", 15 | "file": "ticTacToeResult.cpp" 16 | }, 17 | { 18 | "arguments": [ 19 | "c++", 20 | "-c", 21 | "-std=c++17", 22 | "-Wall", 23 | "-Wextra", 24 | "-Werror", 25 | "-o", 26 | "out/hiddenLoop", 27 | "hiddenLoop.cpp" 28 | ], 29 | "directory": "/home/alexb/work/bookCode/chapter7", 30 | "file": "hiddenLoop.cpp" 31 | } 32 | ] -------------------------------------------------------------------------------- /Chapter07/makefile: -------------------------------------------------------------------------------- 1 | all: ticTacToeResult hiddenLoop 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | ticTacToeResult: .outputFolder 7 | g++ -std=c++17 ticTacToeResult.cpp -Wall -Wextra -Werror -o out/ticTacToeResult 8 | ./out/ticTacToeResult 9 | 10 | hiddenLoop: .outputFolder 11 | g++ -std=c++17 hiddenLoop.cpp -Wall -Wextra -Werror -o out/hiddenLoop 12 | ./out/hiddenLoop 13 | -------------------------------------------------------------------------------- /Chapter08/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/ticTacToeResult", 12 | "ticTacToeResult.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter8", 15 | "file": "ticTacToeResult.cpp" 16 | }, 17 | { 18 | "arguments": [ 19 | "c++", 20 | "-c", 21 | "-std=c++17", 22 | "-Wall", 23 | "-Wextra", 24 | "-Werror", 25 | "-o", 26 | "out/fromClassToFunctions", 27 | "fromClassToFunctions.cpp" 28 | ], 29 | "directory": "/home/alexb/work/bookCode/chapter8", 30 | "file": "fromClassToFunctions.cpp" 31 | }, 32 | { 33 | "arguments": [ 34 | "c++", 35 | "-c", 36 | "-std=c++17", 37 | "-Wall", 38 | "-Wextra", 39 | "-Werror", 40 | "-o", 41 | "out/ticTacToeResultWithClasses", 42 | "ticTacToeResultWithClasses.cpp" 43 | ], 44 | "directory": "/home/alexb/work/bookCode/chapter8", 45 | "file": "ticTacToeResultWithClasses.cpp" 46 | } 47 | ] -------------------------------------------------------------------------------- /Chapter08/makefile: -------------------------------------------------------------------------------- 1 | all: ticTacToeResult ticTacToeResultWithClasses fromClassToFunctions 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | ticTacToeResult: .outputFolder 7 | g++ -std=c++17 ticTacToeResult.cpp -Wall -Wextra -Werror -o out/ticTacToeResult 8 | ./out/ticTacToeResult 9 | 10 | ticTacToeResultWithClasses: .outputFolder 11 | g++ -std=c++17 ticTacToeResultWithClasses.cpp -Wall -Wextra -Werror -o out/ticTacToeResultWithClasses 12 | ./out/ticTacToeResultWithClasses 13 | 14 | fromClassToFunctions: .outputFolder 15 | g++ -std=c++17 fromClassToFunctions.cpp -Wall -Wextra -Werror -o out/fromClassToFunctions 16 | ./out/fromClassToFunctions 17 | -------------------------------------------------------------------------------- /Chapter09/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/testPureFunctions", 12 | "testPureFunctions.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter9", 15 | "file": "testPureFunctions.cpp" 16 | }, 17 | { 18 | "arguments": [ 19 | "c++", 20 | "-c", 21 | "-std=c++17", 22 | "-Wall", 23 | "-Wextra", 24 | "-Werror", 25 | "-o", 26 | "out/pokerHands", 27 | "pokerHands.cpp" 28 | ], 29 | "directory": "/home/alexb/work/bookCode/chapter9", 30 | "file": "pokerHands.cpp" 31 | } 32 | ] -------------------------------------------------------------------------------- /Chapter09/makefile: -------------------------------------------------------------------------------- 1 | all: testPureFunctions pokerHands 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | testPureFunctions: .outputFolder 7 | g++ -std=c++17 testPureFunctions.cpp -Wall -Wextra -Werror -o out/testPureFunctions 8 | ./out/testPureFunctions 9 | 10 | pokerHands: .outputFolder 11 | g++ -std=c++17 pokerHands.cpp -Wall -Wextra -Werror -o out/pokerHands 12 | ./out/pokerHands 13 | -------------------------------------------------------------------------------- /Chapter09/testPureFunctions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 5 | #include "doctest.h" 6 | 7 | using namespace std; 8 | using namespace std::placeholders; 9 | 10 | TEST_CASE("Greater Than"){ 11 | int first = 3; 12 | int second = 2; 13 | 14 | bool result = greater()(first, second); 15 | 16 | CHECK(result); 17 | } 18 | 19 | TEST_CASE("Not Greater Than when first is less than second"){ 20 | int first = 2; 21 | int second = 3; 22 | 23 | bool result = greater()(first, second); 24 | 25 | CHECK_FALSE(result); 26 | } 27 | 28 | TEST_CASE("Not Greater Than when first equals second"){ 29 | int first = 2; 30 | 31 | bool result = greater()(first, first); 32 | 33 | CHECK_FALSE(result); 34 | } 35 | 36 | TEST_CASE("Greater than") { 37 | struct Data { 38 | int first; 39 | int second; 40 | bool expected; 41 | } data; 42 | 43 | SUBCASE("2 is greater than 1") { data.first = 2; data.second = 1; data.expected = true; } 44 | SUBCASE("2 is not greater than 2") { data.first = 2; data.second = 2; data.expected = false; } 45 | SUBCASE("2 is not greater than 3") { data.first = 2; data.second = 3; data.expected = false; } 46 | 47 | CAPTURE(data); 48 | 49 | CHECK_EQ(greater()(data.first, data.second), data.expected); 50 | } 51 | -------------------------------------------------------------------------------- /Chapter10/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/reactive", 12 | "reactive.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter10", 15 | "file": "reactive.cpp" 16 | } 17 | ] -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/insert.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include "benchmark/config.hpp" 12 | 13 | #include 14 | #include // Phil Nash 15 | #include 16 | #include 17 | #include 18 | 19 | namespace { 20 | 21 | template 22 | auto benchmark_insert_mut_std() 23 | { 24 | return [] (nonius::chronometer meter) 25 | { 26 | auto n = meter.param(); 27 | auto g = Generator{}(n); 28 | 29 | measure(meter, [&] { 30 | auto v = Set{}; 31 | for (auto i = 0u; i < n; ++i) 32 | v.insert(g[i]); 33 | return v; 34 | }); 35 | }; 36 | } 37 | 38 | template 39 | auto benchmark_insert() 40 | { 41 | return [] (nonius::chronometer meter) 42 | { 43 | auto n = meter.param(); 44 | auto g = Generator{}(n); 45 | 46 | measure(meter, [&] { 47 | auto v = Set{}; 48 | for (auto i = 0u; i < n; ++i) 49 | v = v.insert(g[i]); 50 | return v; 51 | }); 52 | }; 53 | } 54 | 55 | } // namespace 56 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-box/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-box/insert.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define DISABLE_GC_BENCHMARKS 10 | #include "generator.ipp" 11 | #include "../insert.ipp" 12 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-box/iter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../iter.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-long/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-long/insert.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define DISABLE_GC_BENCHMARKS 10 | #include "generator.ipp" 11 | #include "../insert.ipp" 12 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-long/iter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../iter.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-short/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-short/insert.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../insert.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/string-short/iter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../iter.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/unsigned/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/unsigned/insert.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../insert.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/set/unsigned/iter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "generator.ipp" 10 | #include "../iter.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/access.ipp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/access.hpp" 10 | #include 11 | 12 | #ifndef MEMORY_T 13 | #error "define the MEMORY_T" 14 | #endif 15 | 16 | NONIUS_BENCHMARK("flex/3", benchmark_access_idx>()) 17 | NONIUS_BENCHMARK("flex/4", benchmark_access_idx>()) 18 | NONIUS_BENCHMARK("flex/5", benchmark_access_idx>()) 19 | NONIUS_BENCHMARK("flex/6", benchmark_access_idx>()) 20 | NONIUS_BENCHMARK("flex/7", benchmark_access_idx>()) 21 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/assoc.ipp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/assoc.hpp" 10 | #include 11 | 12 | #ifndef MEMORY_T 13 | #error "define the MEMORY_T" 14 | #endif 15 | 16 | NONIUS_BENCHMARK("flex/3", benchmark_assoc>()) 17 | NONIUS_BENCHMARK("flex/4", benchmark_assoc>()) 18 | NONIUS_BENCHMARK("flex/5", benchmark_assoc>()) 19 | NONIUS_BENCHMARK("flex/6", benchmark_assoc>()) 20 | NONIUS_BENCHMARK("flex/7", benchmark_assoc>()) 21 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/basic/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T basic_memory 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/basic/assoc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T basic_memory 10 | #include "../assoc.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/basic/concat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T basic_memory 10 | #include "../concat.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/basic/push.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T basic_memory 10 | #include "../push.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/concat.ipp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/concat.hpp" 10 | #include 11 | 12 | #ifndef MEMORY_T 13 | #error "define the MEMORY_T" 14 | #endif 15 | 16 | NONIUS_BENCHMARK("flex/3", benchmark_concat>()) 17 | NONIUS_BENCHMARK("flex/4", benchmark_concat>()) 18 | NONIUS_BENCHMARK("flex/5", benchmark_concat>()) 19 | NONIUS_BENCHMARK("flex/6", benchmark_concat>()) 20 | NONIUS_BENCHMARK("flex/7", benchmark_concat>()) 21 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/gc/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T gc_memory 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/gc/assoc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T gc_memory 10 | #include "../assoc.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/gc/concat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T gc_memory 10 | #include "../concat.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/gc/push.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T gc_memory 10 | #include "../push.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/push.ipp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/push.hpp" 10 | #include 11 | 12 | #ifndef MEMORY_T 13 | #error "define the MEMORY_T" 14 | #endif 15 | 16 | NONIUS_BENCHMARK("flex/3", benchmark_push>()) 17 | NONIUS_BENCHMARK("flex/4", benchmark_push>()) 18 | NONIUS_BENCHMARK("flex/5", benchmark_push>()) 19 | NONIUS_BENCHMARK("flex/6", benchmark_push>()) 20 | NONIUS_BENCHMARK("flex/7", benchmark_push>()) 21 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/safe/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T safe_memory 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/safe/assoc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T safe_memory 10 | #include "../assoc.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/safe/concat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T safe_memory 10 | #include "../concat.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/safe/push.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T safe_memory 10 | #include "../push.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/unsafe/access.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T unsafe_memory 10 | #include "../access.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/unsafe/assoc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T unsafe_memory 10 | #include "../assoc.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/unsafe/concat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T unsafe_memory 10 | #include "../concat.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/branching/unsafe/push.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #define MEMORY_T unsafe_memory 10 | #include "../push.ipp" 11 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/misc/push-front.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/push_front.hpp" 10 | 11 | #include 12 | 13 | #if IMMER_BENCHMARK_LIBRRB 14 | extern "C" { 15 | #define restrict __restrict__ 16 | #include 17 | #undef restrict 18 | } 19 | #endif 20 | 21 | #if IMMER_BENCHMARK_LIBRRB 22 | NONIUS_BENCHMARK("librrb", benchmark_push_front_librrb) 23 | #endif 24 | NONIUS_BENCHMARK("flex/4B", bechmark_push_front>()) 25 | NONIUS_BENCHMARK("flex/5B", bechmark_push_front>()) 26 | NONIUS_BENCHMARK("flex/6B", bechmark_push_front>()) 27 | NONIUS_BENCHMARK("flex/GC", bechmark_push_front>()) 28 | NONIUS_BENCHMARK("flex_s/GC", bechmark_push_front>()) 29 | NONIUS_BENCHMARK("flex/NO", bechmark_push_front>()) 30 | NONIUS_BENCHMARK("flex/UN", bechmark_push_front>()) 31 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/paper/concat.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include "benchmark/vector/concat.hpp" 10 | #include 11 | #include 12 | #include 13 | 14 | NONIUS_BENCHMARK("ours/basic", benchmark_concat_incr>()) 15 | NONIUS_BENCHMARK("ours/safe", benchmark_concat_incr>()) 16 | NONIUS_BENCHMARK("ours/unsafe", benchmark_concat_incr>()) 17 | NONIUS_BENCHMARK("ours/gc", benchmark_concat_incr>()) 18 | NONIUS_BENCHMARK("librrb", benchmark_concat_incr_librrb(make_librrb_vector)) 19 | 20 | NONIUS_BENCHMARK("transient ours/gc", benchmark_concat_incr_mut>()) 21 | NONIUS_BENCHMARK("transient chunkedseq32", benchmark_concat_incr_chunkedseq>()) 22 | NONIUS_BENCHMARK("transient chunkedseq", benchmark_concat_incr_chunkedseq>()) 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/benchmark/vector/push_front.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include "benchmark/vector/common.hpp" 12 | 13 | namespace { 14 | 15 | template 16 | auto bechmark_push_front() 17 | { 18 | return [] (nonius::chronometer meter) 19 | { 20 | auto n = meter.param(); 21 | 22 | measure(meter, [&] { 23 | auto v = Vektor{}; 24 | for (auto i = 0u; i < n; ++i) 25 | v = v.push_front(i); 26 | return v; 27 | }); 28 | }; 29 | } 30 | 31 | auto benchmark_push_front_librrb(nonius::chronometer meter) 32 | { 33 | auto n = meter.param(); 34 | 35 | measure(meter, [&] { 36 | auto v = rrb_create(); 37 | for (auto i = 0u; i < n; ++i) { 38 | auto f = rrb_push(rrb_create(), 39 | reinterpret_cast(i)); 40 | v = rrb_concat(f, v); 41 | } 42 | return v; 43 | }); 44 | } 45 | 46 | } // anonymous namespace 47 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/cmake/FindRRB.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find c-rrb 2 | # Once done, this will define 3 | # 4 | # RRB_FOUND - system has RRB 5 | # RRB_INCLUDE_DIR - the RRB include directories 6 | # RRB_LIBRARIES - link these to use RRB 7 | 8 | find_path(RRB_INCLUDE_DIR rrb.h) 9 | find_library(RRB_LIBRARIES NAMES rrb librrb) 10 | 11 | include(FindPackageHandleStandardArgs) 12 | find_package_handle_standard_args( 13 | RRB DEFAULT_MSG RRB_LIBRARIES RRB_INCLUDE_DIR) 14 | 15 | mark_as_advanced(RRB_INCLUDE_DIR RRB_LIBRARIES) 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/cmake/ImmerUtils.cmake: -------------------------------------------------------------------------------- 1 | 2 | function(immer_target_name_for out_target out_file file) 3 | get_filename_component(_extension ${_file} EXT) 4 | 5 | file(RELATIVE_PATH _relative ${PROJECT_SOURCE_DIR} ${file}) 6 | string(REPLACE "${_extension}" "" _name ${_relative}) 7 | string(REGEX REPLACE "/" "-" _name ${_name}) 8 | set(${out_target} "${_name}" PARENT_SCOPE) 9 | 10 | file(RELATIVE_PATH _relative ${CMAKE_CURRENT_LIST_DIR} ${file}) 11 | string(REPLACE "${_extension}" "" _name ${_relative}) 12 | string(REGEX REPLACE "/" "-" _name ${_name}) 13 | set(${out_file} "${_name}" PARENT_SCOPE) 14 | endfunction() 15 | 16 | function(immer_canonicalize_cmake_booleans) 17 | foreach(var ${ARGN}) 18 | if(${var}) 19 | set(${var} 1 PARENT_SCOPE) 20 | else() 21 | set(${var} 0 PARENT_SCOPE) 22 | endif() 23 | endforeach() 24 | endfunction() 25 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - tools 3 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/default.nix: -------------------------------------------------------------------------------- 1 | with import {}; 2 | 3 | stdenv.mkDerivation rec { 4 | name = "immer-git"; 5 | version = "git"; 6 | src = fetchGit ./.; 7 | nativeBuildInputs = [ cmake ]; 8 | dontBuild = true; 9 | meta = with stdenv.lib; { 10 | homepage = "https://github.com/arximboldi/immer"; 11 | description = "Postmodern immutable data structures for C++"; 12 | license = licenses.lgpl3Plus; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Targets 3 | # ======= 4 | 5 | add_custom_target(doxygen 6 | COMMAND doxygen doxygen.config 7 | WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") 8 | 9 | add_custom_target(docs 10 | COMMAND make html 11 | WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") 12 | add_dependencies(docs doxygen) 13 | 14 | set(immer_ssh_method 15 | ssh -p 5488 16 | -o StrictHostKeyChecking=no 17 | -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key) 18 | 19 | add_custom_target(upload-docs 20 | COMMAND 21 | rsync -av -e \"${immer_ssh_method}\" 22 | ${CMAKE_SOURCE_DIR}/doc/_build/html/* 23 | raskolnikov@sinusoid.es:public/immer/) 24 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/algorithms.rst: -------------------------------------------------------------------------------- 1 | 2 | Algorithms 3 | ========== 4 | 5 | This module provides overloads of standard algorithms that leverage 6 | the internal structure of the immutable containers to provide faster 7 | iteration. These are drop-in replacements of the respective STL 8 | algorithms that can be a few times faster when applied on immutable 9 | sequences. 10 | 11 | For further convenience they can be passed in just a container where 12 | the standard library algorithms require being passed in two iterators. 13 | 14 | .. note:: 15 | 16 | They are a similar idea to `structure-aware iterators`_ 17 | but implemented using higher order functions in order to support 18 | structures of any depth. The downside is that this sometimes 19 | causes the compiler to generate bigger executable files. 20 | 21 | .. _structure-aware iterators: https://www.youtube.com/watch?v=T3oA3zAMH9M 22 | 23 | 24 | ----- 25 | 26 | .. doxygengroup:: algorithm 27 | :project: immer 28 | :content-only: 29 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/doxygen.config: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "immer" 2 | OUTPUT_DIRECTORY = _doxygen 3 | GENERATE_LATEX = NO 4 | GENERATE_MAN = NO 5 | GENERATE_RTF = NO 6 | GENERATE_HTML = NO 7 | GENERATE_XML = YES 8 | INPUT = \ 9 | ../immer \ 10 | ../immer/heap \ 11 | ../immer/refcount \ 12 | ../immer/transience 13 | INCLUDE_PATH = .. 14 | QUIET = YES 15 | 16 | JAVADOC_AUTOBRIEF = YES 17 | ENABLE_PREPROCESSING = YES 18 | MARKDOWN_SUPPORT = YES 19 | 20 | ALIASES = "rst=\verbatim embed:rst:leading-asterisk\n" 21 | ALIASES += "endrst=\n\endverbatim" 22 | ALIASES += "rst{1}=\rst\1\endrst" 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/guile.rst: -------------------------------------------------------------------------------- 1 | ../extra/guile/README.rst -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/implementation.rst: -------------------------------------------------------------------------------- 1 | Implementation overview 2 | ======================= 3 | 4 | .. image:: https://upload.wikimedia.org/wikipedia/commons/e/e6/%22Work_in_progress%22%2C_animated.gif 5 | :alt: Work in Progress 6 | :align: center 7 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. include:: ../README.rst 3 | :end-before: include:index/end 4 | 5 | Contents 6 | -------- 7 | 8 | .. toctree:: 9 | :caption: User Manual 10 | :maxdepth: 3 11 | 12 | introduction 13 | containers 14 | transients 15 | algorithms 16 | memory 17 | 18 | .. toctree:: 19 | :caption: Experimental 20 | :maxdepth: 3 21 | 22 | python 23 | guile 24 | 25 | ---- 26 | 27 | * :ref:`genindex` 28 | * :ref:`modindex` 29 | * :ref:`search` 30 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/introduction.rst: -------------------------------------------------------------------------------- 1 | 2 | Introduction 3 | ============ 4 | 5 | .. include:: ../README.rst 6 | :start-after: include:introduction/start 7 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/python.rst: -------------------------------------------------------------------------------- 1 | ../extra/python/README.rst -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/doc/requirements.txt: -------------------------------------------------------------------------------- 1 | git+https://github.com/arximboldi/sphinx.git 2 | git+https://github.com/arximboldi/breathe.git 3 | recommonmark 4 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Targets 3 | # ======= 4 | 5 | add_custom_target(examples 6 | COMMENT "Build all examples.") 7 | add_dependencies(check examples) 8 | 9 | file(GLOB_RECURSE immer_examples "*.cpp") 10 | foreach(_file IN LISTS immer_examples) 11 | immer_target_name_for(_target _output "${_file}") 12 | add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") 13 | add_dependencies(examples ${_target}) 14 | set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) 15 | target_link_libraries(${_target} PUBLIC immer-dev) 16 | add_test("example/${_output}" ${_output}) 17 | endforeach() 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/box/box.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | { 16 | // include:update/start 17 | auto v1 = immer::box{"hello"}; 18 | auto v2 = v1.update([&] (auto l) { 19 | return l + ", world!"; 20 | }); 21 | 22 | assert((v1 == immer::box{"hello"})); 23 | assert((v2 == immer::box{"hello, world!"})); 24 | // include:update/end 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/map/intro.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | // include:intro/start 11 | #include 12 | int main() 13 | { 14 | const auto v0 = immer::map{}; 15 | const auto v1 = v0.set("hello", 42); 16 | assert(v0["hello"] == 0); 17 | assert(v1["hello"] == 42); 18 | 19 | const auto v2 = v1.erase("hello"); 20 | assert(*v1.find("hello") == 42); 21 | assert(!v2.find("hello")); 22 | } 23 | // include:intro/end 24 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/set/intro.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // include:intro/start 10 | #include 11 | int main() 12 | { 13 | const auto v0 = immer::set{}; 14 | const auto v1 = v0.insert(42); 15 | assert(v0.count(42) == 0); 16 | assert(v1.count(42) == 1); 17 | 18 | const auto v2 = v1.erase(42); 19 | assert(v1.count(42) == 1); 20 | assert(v2.count(42) == 0); 21 | } 22 | // include:intro/end 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/fizzbuzz.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // include:fizzbuzz/start 14 | immer::vector fizzbuzz(immer::vector v, int first, int last) 15 | { 16 | for (auto i = first; i < last; ++i) 17 | v = std::move(v).push_back( 18 | i % 15 == 0 ? "FizzBuzz" : 19 | i % 5 == 0 ? "Bizz" : 20 | i % 3 == 0 ? "Fizz" : 21 | /* else */ std::to_string(i)); 22 | return v; 23 | } 24 | // include:fizzbuzz/end 25 | 26 | int main() 27 | { 28 | auto v = fizzbuzz({}, 0, 100); 29 | std::copy(v.begin(), v.end(), 30 | std::ostream_iterator{ 31 | std::cout, "\n"}); 32 | } 33 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // include:example/start 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | // declare a memory policy for using a tracing garbage collector 19 | using gc_policy = immer::memory_policy< 20 | immer::heap_policy, 21 | immer::no_refcount_policy, 22 | immer::gc_transience_policy, 23 | false>; 24 | 25 | // alias the vector type so we are not concerned about memory policies 26 | // in the places where we actually use it 27 | template 28 | using my_vector = immer::vector; 29 | 30 | int main() 31 | { 32 | auto v = my_vector() 33 | .push_back("hello, ") 34 | .push_back("world!\n"); 35 | 36 | for (auto s : v) std::cout << s; 37 | } 38 | // include:example/end 39 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/intro.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // include:intro/start 10 | #include 11 | int main() 12 | { 13 | const auto v0 = immer::vector{}; 14 | const auto v1 = v0.push_back(13); 15 | assert((v0 == immer::vector{})); 16 | assert((v1 == immer::vector{13})); 17 | 18 | const auto v2 = v1.set(0, 42); 19 | assert(v1[0] == 13); 20 | assert(v2[0] == 42); 21 | } 22 | // include:intro/end 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/iota-move.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | // include:myiota/start 13 | immer::vector myiota(immer::vector v, int first, int last) 14 | { 15 | for (auto i = first; i < last; ++i) 16 | v = std::move(v).push_back(i); 17 | return v; 18 | } 19 | // include:myiota/end 20 | 21 | int main() 22 | { 23 | auto v = myiota({}, 0, 100); 24 | std::copy(v.begin(), v.end(), 25 | std::ostream_iterator{ 26 | std::cout, "\n"}); 27 | } 28 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/iota-slow.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | // include:myiota/start 13 | immer::vector myiota(immer::vector v, int first, int last) 14 | { 15 | for (auto i = first; i < last; ++i) 16 | v = v.push_back(i); 17 | return v; 18 | } 19 | // include:myiota/end 20 | 21 | int main() 22 | { 23 | auto v = myiota({}, 0, 100); 24 | std::copy(v.begin(), v.end(), 25 | std::ostream_iterator{ 26 | std::cout, "\n"}); 27 | } 28 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/iota-transient-std.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // include:myiota/start 15 | immer::vector myiota(immer::vector v, int first, int last) 16 | { 17 | auto t = v.transient(); 18 | std::generate_n(std::back_inserter(t), 19 | last - first, 20 | [&] { return first++; }); 21 | return t.persistent(); 22 | } 23 | // include:myiota/end 24 | 25 | int main() 26 | { 27 | auto v = myiota({}, 0, 100); 28 | std::copy(v.begin(), v.end(), 29 | std::ostream_iterator{ 30 | std::cout, "\n"}); 31 | } 32 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/iota-transient.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // include:myiota/start 14 | immer::vector myiota(immer::vector v, int first, int last) 15 | { 16 | auto t = v.transient(); 17 | for (auto i = first; i < last; ++i) 18 | t.push_back(i); 19 | return t.persistent(); 20 | } 21 | // include:myiota/end 22 | 23 | int main() 24 | { 25 | auto v = myiota({}, 0, 100); 26 | std::copy(v.begin(), v.end(), 27 | std::ostream_iterator{ 28 | std::cout, "\n"}); 29 | } 30 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/example/vector/move.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | // include:move-bad/start 13 | immer::vector do_stuff(const immer::vector v) 14 | { 15 | return std::move(v).push_back(42); 16 | } 17 | // include:move-bad/end 18 | 19 | // include:move-good/start 20 | immer::vector do_stuff_better(immer::vector v) 21 | { 22 | return std::move(v).push_back(42); 23 | } 24 | // include:move-good/end 25 | 26 | int main() 27 | { 28 | auto v = immer::vector{}; 29 | auto v1 = do_stuff(v); 30 | auto v2 = do_stuff_better(v); 31 | assert(v1.size() == 1); 32 | assert(v2.size() == 1); 33 | assert(v1[0] == 42); 34 | assert(v2[0] == 42); 35 | } 36 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/fuzzer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_custom_target(fuzzers 3 | COMMENT "Build all fuzzers.") 4 | 5 | file(GLOB_RECURSE immer_fuzzers "*.cpp") 6 | foreach(_file IN LISTS immer_fuzzers) 7 | immer_target_name_for(_target _output "${_file}") 8 | add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") 9 | set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) 10 | target_compile_options(${_target} PUBLIC 11 | "-fsanitize=address" 12 | "-fsanitize-coverage=trace-pc-guard") 13 | target_link_libraries(${_target} PUBLIC 14 | "-fsanitize=address" 15 | immer-dev 16 | Fuzzer 17 | ${LIBGC_LIBS}) 18 | target_include_directories(${_target} SYSTEM PUBLIC 19 | ${LIBGC_INCLUDE_DIR}) 20 | add_dependencies(fuzzers ${_target}) 21 | endforeach() 22 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(PkgConfig) 3 | 4 | pkg_check_modules(Guile guile-2.2) 5 | 6 | if (NOT Guile_FOUND) 7 | message(STATUS "Disabling Guile modules") 8 | return() 9 | endif() 10 | 11 | set(GUILE_EXTENSION_DIR ${CMAKE_CURRENT_BINARY_DIR}) 12 | configure_file(immer.scm.in immer.scm) 13 | 14 | add_library(guile-immer SHARED EXCLUDE_FROM_ALL 15 | src/immer.cpp) 16 | target_include_directories(guile-immer PUBLIC 17 | ${CMAKE_CURRENT_SOURCE_DIR} 18 | ${CALLABLE_TRAITS_INCLUDE_DIR} 19 | ${Guile_INCLUDE_DIRS}) 20 | target_link_libraries(guile-immer PUBLIC 21 | immer 22 | ${Guile_LIBRARIES}) 23 | 24 | add_custom_target(guile DEPENDS guile-immer) 25 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/immer.scm.in: -------------------------------------------------------------------------------- 1 | (define-module (immer)) 2 | 3 | ;; The extension automatically exports the names via 'scm_c_export' 4 | (load-extension "@GUILE_EXTENSION_DIR@/libguile-immer" 5 | "init_immer") 6 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/detail/define.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #ifndef SCM_AUTO_EXPORT 12 | #define SCM_AUTO_EXPORT 1 13 | #endif 14 | 15 | #include 16 | #include 17 | 18 | namespace scm { 19 | namespace detail { 20 | 21 | template 22 | static void define_impl(const std::string& name, Fn fn) 23 | { 24 | using args_t = function_args_t; 25 | constexpr auto args_size = pack_size_v; 26 | constexpr auto has_rest = std::is_same, scm::args>{}; 27 | constexpr auto arg_count = args_size - has_rest; 28 | auto subr = (scm_t_subr) +subr_wrapper_aux(fn, args_t{}); 29 | scm_c_define_gsubr(name.c_str(), arg_count, 0, has_rest, subr); 30 | #if SCM_AUTO_EXPORT 31 | scm_c_export(name.c_str()); 32 | #endif 33 | } 34 | 35 | } // namespace detail 36 | } // namespace scm 37 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/detail/function_args.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | namespace scm { 15 | namespace detail { 16 | 17 | template 18 | using function_args_t = boost::callable_traits::args_t; 19 | 20 | } // namespace detail 21 | } // namespace scm 22 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/detail/invoke.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | // Adapted from the official std::invoke proposal: 12 | // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html 13 | 14 | #include 15 | #include 16 | 17 | namespace scm { 18 | namespace detail { 19 | 20 | template 21 | std::enable_if_t< 22 | std::is_member_pointer>::value, 23 | std::result_of_t> 24 | invoke(Functor&& f, Args&&... args) 25 | { 26 | return std::mem_fn(f)(std::forward(args)...); 27 | } 28 | 29 | template 30 | std::enable_if_t< 31 | !std::is_member_pointer>::value, 32 | std::result_of_t> 33 | invoke(Functor&& f, Args&&... args) 34 | { 35 | return std::forward(f)(std::forward(args)...); 36 | } 37 | 38 | } // namespace detail 39 | } // namespace scm 40 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/detail/pack.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | namespace scm { 12 | namespace detail { 13 | 14 | struct none_t; 15 | 16 | template 17 | struct pack {}; 18 | 19 | template 20 | struct pack_size; 21 | 22 | template 23 | struct pack_size> 24 | { 25 | static constexpr auto value = sizeof...(Ts); 26 | }; 27 | 28 | template 29 | constexpr auto pack_size_v = pack_size::value; 30 | 31 | template 32 | struct pack_last 33 | { 34 | using type = none_t; 35 | }; 36 | 37 | template 38 | struct pack_last> 39 | : pack_last> 40 | {}; 41 | 42 | template 43 | struct pack_last> 44 | { 45 | using type = T; 46 | }; 47 | 48 | template 49 | using pack_last_t = typename pack_last::type; 50 | 51 | } // namespace detail 52 | } // namespace scm 53 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/detail/util.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace scm { 14 | namespace detail { 15 | 16 | #define SCM_DECLTYPE_RETURN(...) \ 17 | decltype(__VA_ARGS__) \ 18 | { return __VA_ARGS__; } \ 19 | /**/ 20 | 21 | template 22 | constexpr bool is_valid_v = true; 23 | 24 | template 25 | using is_valid_t = void; 26 | 27 | template 28 | void check_call_once() 29 | { 30 | static bool called = false; 31 | if (called) scm_misc_error (nullptr, "Double defined binding. \ 32 | This may be caused because there are multiple C++ binding groups in the same \ 33 | translation unit. You may solve this by using different type tags for each \ 34 | binding group.", SCM_EOL); 35 | called = true; 36 | } 37 | 38 | struct move_sequence 39 | { 40 | move_sequence() = default; 41 | move_sequence(const move_sequence&) = delete; 42 | move_sequence(move_sequence&& other) 43 | { other.moved_from_ = true; }; 44 | 45 | bool moved_from_ = false; 46 | }; 47 | 48 | } // namespace detail 49 | } // namespace scm 50 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/list.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | namespace scm { 15 | 16 | struct list : detail::wrapper 17 | { 18 | using base_t = detail::wrapper; 19 | using base_t::base_t; 20 | 21 | using iterator = list; 22 | using value_type = val; 23 | 24 | list() : base_t{SCM_EOL} {}; 25 | list end() const { return {}; } 26 | list begin() const { return *this; } 27 | 28 | explicit operator bool() { return handle_ != SCM_EOL; } 29 | 30 | val operator* () const { return val{scm_car(handle_)}; } 31 | 32 | list& operator++ () 33 | { 34 | handle_ = scm_cdr(handle_); 35 | return *this; 36 | } 37 | 38 | list operator++ (int) 39 | { 40 | auto result = *this; 41 | result.handle_ = scm_cdr(handle_); 42 | return result; 43 | } 44 | }; 45 | 46 | struct args : list 47 | { 48 | using list::list; 49 | }; 50 | 51 | } // namespace scm 52 | 53 | SCM_DECLARE_WRAPPER_TYPE(scm::list); 54 | SCM_DECLARE_WRAPPER_TYPE(scm::args); 55 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/guile/scm/scm.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/js/makefile: -------------------------------------------------------------------------------- 1 | 2 | BOOST=. 3 | EMCXX=em++ 4 | EMCXXFLAGS=-O3 -std=c++14 --bind \ 5 | -I ../.. \ 6 | -I $(BOOST) 7 | WASM_BACKEND=0 8 | 9 | ALL= \ 10 | out/immer.asmjs.js \ 11 | out/immer.asmjs.html \ 12 | out/immer.wasm.js \ 13 | out/immer.wasm.html 14 | 15 | all: $(ALL) 16 | 17 | out/immer.asmjs.js: immer.cpp 18 | @mkdir -p $(@D) 19 | $(EMCXX) $(EMCXXFLAGS) $< -o $@ 20 | 21 | out/immer.wasm.js: immer.cpp 22 | @mkdir -p $(@D) 23 | EMCC_WASM_BACKEND=$(WASM_BACKEND) $(EMCXX) -s WASM=1 $(EMCXXFLAGS) $< -o $@ 24 | 25 | %.html: %.js index.tpl.html 26 | sed s/%IMMER_JS%/`basename $<`/ < index.tpl.html > $@ 27 | 28 | clean: 29 | rm -f $(ALL) 30 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | option(USE_PYBIND "bind with pybind1" off) 3 | option(USE_BOOST_PYTHON "bind with boost::python" off) 4 | 5 | if (USE_PYBIND) 6 | set(PYBIND11_CPP_STANDARD -std=c++14) 7 | find_package(Boost 1.56 REQUIRED) 8 | add_subdirectory(lib/pybind11) 9 | pybind11_add_module(immer_python_module src/immer-pybind.cpp) 10 | target_link_libraries(immer_python_module PUBLIC 11 | immer) 12 | 13 | elseif(USE_BOOST_PYTHON) 14 | find_package(PythonInterp) 15 | find_package(PythonLibs) 16 | find_package(Boost 1.56 COMPONENTS python) 17 | python_add_module(immer_python_module src/immer-boost.cpp) 18 | include_directories(immer_python_module PUBLIC 19 | ${immer_include_dir} 20 | ${Boost_INCLUDE_DIRS} 21 | ${PYTHON_INCLUDE_DIRS}) 22 | target_link_libraries(immer_python_module PUBLIC 23 | immer 24 | ${Boost_LIBRARIES} 25 | ${PYTHON_LIBRARIES}) 26 | 27 | else() 28 | find_package(PythonInterp) 29 | find_package(PythonLibs) 30 | 31 | if (NOT PYTHONLIBS_FOUND) 32 | message(STATUS "Disabling Python modules") 33 | return() 34 | endif() 35 | 36 | python_add_module(immer_python_module EXCLUDE_FROM_ALL 37 | src/immer-raw.cpp) 38 | target_include_directories(immer_python_module PUBLIC 39 | ${PYTHON_INCLUDE_DIRS}) 40 | target_link_libraries(immer_python_module PUBLIC 41 | immer 42 | ${PYTHON_LIBRARIES}) 43 | 44 | endif() 45 | 46 | add_custom_target(python DEPENDS immer_python_module) 47 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/python/README.rst: -------------------------------------------------------------------------------- 1 | 2 | Python bindings 3 | =============== 4 | 5 | This library includes experimental bindings bring efficient immutable 6 | vectors for the Python language. They were developed as part of the 7 | research for the `ICFP'17 paper`_. The interface is quite 8 | **incomplete**, yet you can already do some things like: 9 | 10 | .. literalinclude:: ../extra/python/example.py 11 | :language: python 12 | :start-after: intro/start 13 | :end-before: intro/end 14 | .. 15 | 16 | **Do you want to help** making these bindings complete and production 17 | ready? Drop a line at `immer@sinusoid.al 18 | `_ or `open an issue on Github 19 | `_ 20 | 21 | Installation 22 | ------------ 23 | :: 24 | 25 | pip install --user git+https://github.com/arximboldi/immer.git 26 | 27 | Benchmarks 28 | ---------- 29 | 30 | The library includes a set of benchmarks that compare it to 31 | `pyrsistent `_. You can see the 32 | results in the `ICFP'17 paper`_. If you want to run them yourself, 33 | you need to install some dependencies:: 34 | 35 | pip install --user pytest-benchmark pyrsistent 36 | 37 | Then you need to clone the `project repository 38 | `_ and from its root, run:: 39 | 40 | pytest extra/python/benchmark 41 | 42 | .. _ICFP'17 paper: https://public.sinusoid.es/misc/immer/immer-icfp17.pdf 43 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/python/benchmark/test_benchmarks.py: -------------------------------------------------------------------------------- 1 | 2 | # immer: immutable data structures for C++ 3 | # Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | # 5 | # This software is distributed under the Boost Software License, Version 1.0. 6 | # See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | 8 | ## 9 | 10 | import immer 11 | import pyrsistent 12 | 13 | BENCHMARK_SIZE = 1000 14 | 15 | def push(v, n=BENCHMARK_SIZE): 16 | for x in xrange(n): 17 | v = v.append(x) 18 | return v 19 | 20 | def assoc(v): 21 | for i in xrange(len(v)): 22 | v = v.set(i, i+1) 23 | return v 24 | 25 | def index(v): 26 | for i in xrange(len(v)): 27 | v[i] 28 | 29 | def test_push_immer(benchmark): 30 | benchmark(push, immer.Vector()) 31 | 32 | def test_push_pyrsistent(benchmark): 33 | benchmark(push, pyrsistent.pvector()) 34 | 35 | def test_assoc_immer(benchmark): 36 | benchmark(assoc, push(immer.Vector())) 37 | 38 | def test_assoc_pyrsistent(benchmark): 39 | benchmark(assoc, push(pyrsistent.pvector())) 40 | 41 | def test_index_immer(benchmark): 42 | benchmark(index, push(immer.Vector())) 43 | 44 | def test_index_pyrsistent(benchmark): 45 | benchmark(index, push(pyrsistent.pvector())) 46 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/python/example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python## 2 | 3 | # immer: immutable data structures for C++ 4 | # Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 5 | # 6 | # This software is distributed under the Boost Software License, Version 1.0. 7 | # See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 8 | 9 | 10 | # include:intro/start 11 | import immer 12 | 13 | v0 = immer.Vector().append(13).append(42) 14 | assert v0[0] == 13 15 | assert v0[1] == 42 16 | assert len(v0) == 2 17 | 18 | v1 = v0.set(0, 12) 19 | assert v0.tolist() == [13, 42] 20 | assert v1.tolist() == [12, 42] 21 | # include:intro/end 22 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/extra/python/immer/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from immer_python_module import * 3 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/detail/rbts/bits.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | namespace detail { 15 | namespace rbts { 16 | 17 | using bits_t = std::uint32_t; 18 | using shift_t = std::uint32_t; 19 | using count_t = std::uint32_t; 20 | using size_t = std::size_t; 21 | 22 | template 23 | constexpr T branches = T{1} << B; 24 | 25 | template 26 | constexpr T mask = branches - 1; 27 | 28 | template 29 | constexpr shift_t endshift = shift_t{BL} - shift_t{B}; 30 | 31 | } // namespace rbts 32 | } // namespace detail 33 | } // namespace immer 34 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/detail/ref_count_base.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | namespace detail { 15 | 16 | template 17 | struct ref_count_base 18 | { 19 | mutable std::atomic ref_count { 0 }; 20 | 21 | friend void intrusive_ptr_add_ref(const Deriv* x) 22 | { 23 | x->ref_count.fetch_add(1, std::memory_order_relaxed); 24 | } 25 | 26 | friend void intrusive_ptr_release(const Deriv* x) 27 | { 28 | if (x->ref_count.fetch_sub(1, std::memory_order_release) == 1) { 29 | std::atomic_thread_fence(std::memory_order_acquire); 30 | delete x; 31 | } 32 | } 33 | }; 34 | 35 | } /* namespace detail */ 36 | } /* namespace immer */ 37 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/cpp_heap.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | 15 | /*! 16 | * A heap that uses `operator new` and `operator delete`. 17 | */ 18 | struct cpp_heap 19 | { 20 | /*! 21 | * Returns a pointer to a memory region of size `size`, if the 22 | * allocation was successful, and throws otherwise. 23 | */ 24 | template 25 | static void* allocate(std::size_t size, Tags...) 26 | { 27 | return ::operator new(size); 28 | } 29 | 30 | /*! 31 | * Releases a memory region `data` that was previously returned by 32 | * `allocate`. One must not use nor deallocate again a memory 33 | * region that once it has been deallocated. 34 | */ 35 | static void deallocate(std::size_t size, void* data) 36 | { 37 | ::operator delete(data); 38 | } 39 | }; 40 | 41 | } // namespace immer 42 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/debug_size_heap.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace immer { 16 | 17 | #if IMMER_ENABLE_DEBUG_SIZE_HEAP 18 | 19 | /*! 20 | * A heap that in debug mode ensures that the sizes for allocation and 21 | * deallocation do match. 22 | */ 23 | template 24 | struct debug_size_heap 25 | { 26 | template 27 | static void* allocate(std::size_t size, Tags... tags) 28 | { 29 | auto p = (std::size_t*) Base::allocate(size + sizeof(std::size_t), tags...); 30 | *p = size; 31 | return p + 1; 32 | } 33 | 34 | template 35 | static void deallocate(std::size_t size, void* data, Tags... tags) 36 | { 37 | auto p = ((std::size_t*) data) - 1; 38 | assert(*p == size); 39 | Base::deallocate(size + sizeof(std::size_t), p, tags...); 40 | } 41 | }; 42 | 43 | #else // IMMER_ENABLE_DEBUG_SIZE_HEAP 44 | 45 | template 46 | using debug_size_heap = identity_heap; 47 | 48 | #endif // !IMMER_ENABLE_DEBUG_SIZE_HEAP 49 | 50 | } // namespace immer 51 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/free_list_node.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | 15 | struct free_list_node 16 | { 17 | free_list_node* next; 18 | }; 19 | 20 | template 21 | struct with_free_list_node 22 | : with_data 23 | {}; 24 | 25 | } // namespace immer 26 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/identity_heap.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | 15 | /*! 16 | * A heap that simply passes on to the parent heap. 17 | */ 18 | template 19 | struct identity_heap : Base 20 | { 21 | template 22 | static void* allocate(std::size_t size, Tags... tags) 23 | { 24 | return Base::allocate(size, tags...); 25 | } 26 | 27 | template 28 | static void deallocate(std::size_t size, void* data, Tags... tags) 29 | { 30 | Base::deallocate(size, data, tags...); 31 | } 32 | }; 33 | 34 | } // namespace immer 35 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/malloc_heap.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace immer { 17 | 18 | /*! 19 | * A heap that uses `std::malloc` and `std::free` to manage memory. 20 | */ 21 | struct malloc_heap 22 | { 23 | /*! 24 | * Returns a pointer to a memory region of size `size`, if the 25 | * allocation was successful and throws `std::bad_alloc` otherwise. 26 | */ 27 | template 28 | static void* allocate(std::size_t size, Tags...) 29 | { 30 | auto p = std::malloc(size); 31 | if (IMMER_UNLIKELY(!p)) 32 | throw std::bad_alloc{}; 33 | return p; 34 | } 35 | 36 | /*! 37 | * Releases a memory region `data` that was previously returned by 38 | * `allocate`. One must not use nor deallocate again a memory 39 | * region that once it has been deallocated. 40 | */ 41 | static void deallocate(std::size_t, void* data) 42 | { 43 | std::free(data); 44 | } 45 | }; 46 | 47 | } // namespace immer 48 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/split_heap.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | namespace immer { 15 | 16 | /*! 17 | * Adaptor that uses `SmallHeap` for allocations that are smaller or 18 | * equal to `Size` and `BigHeap` otherwise. 19 | */ 20 | template 21 | struct split_heap 22 | { 23 | template 24 | static void* allocate(std::size_t size, Tags... tags) 25 | { 26 | return size <= Size 27 | ? SmallHeap::allocate(size, tags...) 28 | : BigHeap::allocate(size, tags...); 29 | } 30 | 31 | template 32 | static void deallocate(std::size_t size, void* data, Tags... tags) 33 | { 34 | if (size <= Size) 35 | SmallHeap::deallocate(size, data, tags...); 36 | else 37 | BigHeap::deallocate(size, data, tags...); 38 | } 39 | }; 40 | 41 | } // namespace immer 42 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/tags.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | namespace immer { 12 | 13 | struct norefs_tag {}; 14 | 15 | } // namespace immer 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/heap/with_data.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | 15 | /*! 16 | * Appends a default constructed extra object of type `T` at the 17 | * *before* the requested region. 18 | * 19 | * @tparam T Type of the appended data. 20 | * @tparam Base Type of the parent heap. 21 | */ 22 | template 23 | struct with_data : Base 24 | { 25 | using base_t = Base; 26 | 27 | template 28 | static void* allocate(std::size_t size, Tags... tags) 29 | { 30 | auto p = base_t::allocate(size + sizeof(T), tags...); 31 | return new (p) T{} + 1; 32 | } 33 | 34 | template 35 | static void deallocate(std::size_t size, void* p, Tags... tags) 36 | { 37 | auto dp = static_cast(p) - 1; 38 | dp->~T(); 39 | base_t::deallocate(size + sizeof(T), dp, tags...); 40 | } 41 | }; 42 | 43 | } // namespace immer 44 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/map_transient.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace immer { 17 | 18 | /*! 19 | * **WORK IN PROGRESS** 20 | */ 21 | template , 24 | typename Equal = std::equal_to, 25 | typename MemoryPolicy = default_memory_policy, 26 | detail::hamts::bits_t B = default_bits> 27 | class map_transient; 28 | 29 | } // namespace immer 30 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/refcount/enable_intrusive_ptr.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | namespace immer { 14 | 15 | template 16 | class enable_intrusive_ptr 17 | { 18 | mutable RefcountPolicy refcount_data_; 19 | 20 | public: 21 | enable_intrusive_ptr() 22 | : refcount_data_{disowned{}} 23 | {} 24 | 25 | friend void intrusive_ptr_add_ref(const Deriv* x) 26 | { 27 | x->refcount_data_.inc(); 28 | } 29 | 30 | friend void intrusive_ptr_release(const Deriv* x) 31 | { 32 | if (x->refcount_data_.dec()) 33 | delete x; 34 | } 35 | }; 36 | 37 | } // namespace immer 38 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/refcount/no_refcount_policy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | namespace immer { 12 | 13 | struct disowned {}; 14 | 15 | /*! 16 | * Disables reference counting, to be used with an alternative garbage 17 | * collection strategy like a `gc_heap`. 18 | */ 19 | struct no_refcount_policy 20 | { 21 | no_refcount_policy() {}; 22 | no_refcount_policy(disowned) {} 23 | 24 | void inc() {} 25 | bool dec() { return false; } 26 | void dec_unsafe() {} 27 | bool unique() { return false; } 28 | }; 29 | 30 | } // namespace immer 31 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/refcount/refcount_policy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace immer { 18 | 19 | /*! 20 | * A reference counting policy implemented using an *atomic* `int` 21 | * count. It is **thread-safe**. 22 | */ 23 | struct refcount_policy 24 | { 25 | mutable std::atomic refcount; 26 | 27 | refcount_policy() : refcount{1} {}; 28 | refcount_policy(disowned) : refcount{0} {} 29 | 30 | void inc() 31 | { 32 | refcount.fetch_add(1, std::memory_order_relaxed); 33 | } 34 | 35 | bool dec() 36 | { 37 | return 1 == refcount.fetch_sub(1, std::memory_order_acq_rel); 38 | } 39 | 40 | void dec_unsafe() 41 | { 42 | assert(refcount.load() > 1); 43 | refcount.fetch_sub(1, std::memory_order_relaxed); 44 | } 45 | 46 | bool unique() 47 | { 48 | return refcount == 1; 49 | } 50 | }; 51 | 52 | } // namespace immer 53 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/refcount/unsafe_refcount_policy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace immer { 17 | 18 | /*! 19 | * A reference counting policy implemented using a raw `int` count. 20 | * It is **not thread-safe**. 21 | */ 22 | struct unsafe_refcount_policy 23 | { 24 | mutable int refcount; 25 | 26 | unsafe_refcount_policy() : refcount{1} {}; 27 | unsafe_refcount_policy(disowned) : refcount{0} {} 28 | 29 | void inc() { ++refcount; } 30 | bool dec() { return --refcount == 0; } 31 | void dec_unsafe() { --refcount; } 32 | bool unique() { return refcount == 1; } 33 | }; 34 | 35 | } // namespace immer 36 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/set_transient.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace immer { 17 | 18 | /*! 19 | * **WORK IN PROGRESS** 20 | */ 21 | template , 23 | typename Equal = std::equal_to, 24 | typename MemoryPolicy = default_memory_policy, 25 | detail::hamts::bits_t B = default_bits> 26 | class set_transient; 27 | 28 | } // namespace immer 29 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/immer/transience/no_transience_policy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | namespace immer { 12 | 13 | /*! 14 | * Disables any special *transience* tracking. To be used when 15 | * *reference counting* is available instead. 16 | */ 17 | struct no_transience_policy 18 | { 19 | template 20 | struct apply 21 | { 22 | struct type 23 | { 24 | struct edit {}; 25 | 26 | struct owner 27 | { 28 | operator edit () const { return {}; } 29 | owner& operator=(const owner&) { return *this; }; 30 | }; 31 | 32 | struct ownee 33 | { 34 | ownee& operator=(edit) { return *this; }; 35 | bool can_mutate(edit) const { return false; } 36 | bool owned() const { return false; } 37 | }; 38 | 39 | static owner noone; 40 | }; 41 | }; 42 | }; 43 | 44 | template 45 | typename no_transience_policy::apply::type::owner 46 | no_transience_policy::apply::type::noone = {}; 47 | 48 | } // namespace immer 49 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/nix/docs.nix: -------------------------------------------------------------------------------- 1 | { nixpkgs ? }: 2 | 3 | with import nixpkgs {}; 4 | 5 | rec { 6 | breathe = with python27Packages; buildPythonPackage rec { 7 | version = "git-arximboldi-${commit}"; 8 | pname = "breathe"; 9 | name = "${pname}-${version}"; 10 | commit = "5074aecb5ad37bb70f50216eaa01d03a375801ec"; 11 | src = fetchFromGitHub { 12 | owner = "arximboldi"; 13 | repo = "breathe"; 14 | rev = commit; 15 | sha256 = "10kkh3wb0ggyxx1a7x50aklhhw0cq269g3jddf2gb3pv9gpbj7sa"; 16 | }; 17 | propagatedBuildInputs = [ docutils sphinx ]; 18 | meta = with stdenv.lib; { 19 | homepage = https://github.com/michaeljones/breathe; 20 | license = licenses.bsd3; 21 | description = "Sphinx Doxygen renderer"; 22 | inherit (sphinx.meta) platforms; 23 | }; 24 | }; 25 | 26 | recommonmark = python27Packages.recommonmark; 27 | } 28 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Targets 3 | # ======= 4 | 5 | add_custom_target(tests 6 | COMMENT "Build all the unit tests.") 7 | add_dependencies(check tests) 8 | 9 | include(CTest) 10 | 11 | file(GLOB_RECURSE immer_unit_tests "*.cpp") 12 | foreach(_file IN LISTS immer_unit_tests) 13 | immer_target_name_for(_target _output "${_file}") 14 | add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") 15 | set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) 16 | add_dependencies(tests ${_target}) 17 | target_compile_definitions(${_target} PUBLIC 18 | DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 19 | CATCH_CONFIG_MAIN) 20 | target_link_libraries(${_target} PUBLIC immer-dev) 21 | add_test("test/${_output}" ${_output}) 22 | endforeach() 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/array/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define VECTOR_T ::immer::array 12 | #include "../vector/generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/array/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using gc_memory = immer::memory_policy< 14 | immer::heap_policy, 15 | immer::no_refcount_policy, 16 | immer::gc_transience_policy, 17 | false>; 18 | 19 | template 20 | using test_array_t = immer::array; 21 | 22 | #define VECTOR_T test_array_t 23 | #include "../vector/generic.ipp" 24 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/array_transient/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #define VECTOR_T ::immer::array 13 | #define VECTOR_TRANSIENT_T ::immer::array_transient 14 | 15 | #include "../vector_transient/generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/array_transient/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | using gc_memory = immer::memory_policy< 16 | immer::heap_policy, 17 | immer::no_refcount_policy, 18 | immer::gc_transience_policy, 19 | false>; 20 | 21 | template 22 | using test_array_t = immer::array; 23 | 24 | template 25 | using test_array_transient_t = immer::array_transient; 26 | 27 | #define VECTOR_T test_array_t 28 | #define VECTOR_TRANSIENT_T test_array_transient_t 29 | 30 | #include "../vector_transient/generic.ipp" 31 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/box/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define BOX_T ::immer::box 12 | #include "generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/box/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using gc_memory = immer::memory_policy< 14 | immer::heap_policy, 15 | immer::no_refcount_policy>; 16 | 17 | template 18 | using test_box_t = immer::box; 19 | 20 | #define BOX_T test_box_t 21 | #include "generic.ipp" 22 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/box/vector-of-boxes-transient.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | TEST_CASE("issue-33") 16 | { 17 | using Element = immer::box; 18 | auto vect = immer::vector{}; 19 | 20 | // this one works fine 21 | for (auto i = 0; i < 100; ++i) { 22 | vect = vect.push_back(Element("x")); 23 | } 24 | 25 | // this one doesn't compile 26 | auto t = vect.transient(); 27 | 28 | for (auto i = 0; i < 100; ++i) { 29 | t.push_back(Element("x")); 30 | } 31 | 32 | vect = t.persistent(); 33 | 34 | CHECK(*vect[0] == "x"); 35 | CHECK(*vect[99] == "x"); 36 | } 37 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/B3-BL0.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using test_flex_vector_t = 14 | immer::flex_vector; 15 | 16 | template 17 | using test_vector_t = 18 | immer::vector; 19 | 20 | #define FLEX_VECTOR_T test_flex_vector_t 21 | #define VECTOR_T test_vector_t 22 | #include "generic.ipp" 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/B3-BL3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using test_flex_vector_t = 14 | immer::flex_vector; 15 | 16 | template 17 | using test_vector_t = 18 | immer::vector; 19 | 20 | #define FLEX_VECTOR_T test_flex_vector_t 21 | #define VECTOR_T test_vector_t 22 | #include "generic.ipp" 23 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #define FLEX_VECTOR_T ::immer::flex_vector 13 | #define VECTOR_T ::immer::vector 14 | #include "generic.ipp" 15 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using gc_memory = immer::memory_policy< 15 | immer::heap_policy, 16 | immer::no_refcount_policy, 17 | immer::gc_transience_policy, 18 | false>; 19 | 20 | template 21 | using test_flex_vector_t = immer::flex_vector; 22 | 23 | template 24 | using test_vector_t = immer::vector; 25 | 26 | #define FLEX_VECTOR_T test_flex_vector_t 27 | #define VECTOR_T test_vector_t 28 | #include "generic.ipp" 29 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/issue-45.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // Thanks Guiguiprim for reporting this issue 10 | // https://github.com/arximboldi/immer/issues/46 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #if IMMER_CXX_STANDARD >= 17 19 | 20 | #include 21 | 22 | TEST_CASE("error when erasing an element from a immer::flex_vector") 23 | { 24 | using Vector = immer::flex_vector>; 25 | // using Vector = immer::flex_vector>; 26 | // using Vector = immer::flex_vector; 27 | 28 | Vector v{1, 2, 3, 4}; 29 | Vector v2 = v.erase(2); 30 | 31 | CHECK(v2.size() == 3); 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/issue-47.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | immer::flex_vector v{1}; 4 | 5 | int main() 6 | { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/regular-B3-BL3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template 12 | using test_vector_t = 13 | immer::flex_vector; 14 | 15 | #define VECTOR_T test_vector_t 16 | #include "../vector/generic.ipp" 17 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector/regular-default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define VECTOR_T ::immer::flex_vector 12 | #include "../vector/generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector_transient/B3-BL0.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | template 15 | using test_flex_vector_t = immer::flex_vector; 16 | 17 | template 18 | using test_flex_vector_transient_t = typename test_flex_vector_t::transient_type; 19 | 20 | template 21 | using test_vector_t = immer::vector; 22 | 23 | #define FLEX_VECTOR_T test_flex_vector_t 24 | #define FLEX_VECTOR_TRANSIENT_T test_flex_vector_transient_t 25 | #define VECTOR_T test_vector_t 26 | 27 | #include "generic.ipp" 28 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector_transient/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define FLEX_VECTOR_T ::immer::flex_vector 15 | #define FLEX_VECTOR_TRANSIENT_T ::immer::flex_vector_transient 16 | #define VECTOR_T ::immer::vector 17 | #include "generic.ipp" 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector_transient/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using gc_memory = immer::memory_policy< 17 | immer::heap_policy, 18 | immer::no_refcount_policy, 19 | immer::gc_transience_policy, 20 | false>; 21 | 22 | template 23 | using test_flex_vector_t = immer::flex_vector; 24 | 25 | template 26 | using test_vector_t = immer::vector; 27 | 28 | template 29 | using test_flex_vector_transient_t = immer::flex_vector_transient; 30 | 31 | #define FLEX_VECTOR_T test_flex_vector_t 32 | #define FLEX_VECTOR_TRANSIENT_T test_flex_vector_transient_t 33 | #define VECTOR_T test_vector_t 34 | #include "generic.ipp" 35 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector_transient/regular-default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #define VECTOR_T ::immer::flex_vector 13 | #define VECTOR_TRANSIENT_T ::immer::flex_vector_transient 14 | 15 | #include "../vector_transient/generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/flex_vector_transient/regular-gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using gc_memory = immer::memory_policy< 17 | immer::heap_policy, 18 | immer::no_refcount_policy, 19 | immer::gc_transience_policy, 20 | false>; 21 | 22 | template 23 | using test_flex_vector_t = immer::flex_vector; 24 | 25 | template 26 | using test_flex_vector_transient_t = immer::flex_vector_transient; 27 | 28 | #define VECTOR_T test_flex_vector_t 29 | #define VECTOR_TRANSIENT_T test_flex_vector_transient_t 30 | 31 | #include "../vector_transient/generic.ipp" 32 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/map/B3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template , 13 | typename Eq = std::equal_to> 14 | using test_map_t = immer::map; 15 | 16 | #define MAP_T test_map_t 17 | #include "generic.ipp" 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/map/B6.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template , 13 | typename Eq = std::equal_to> 14 | using test_map_t = immer::map; 15 | 16 | #define MAP_T test_map_t 17 | #include "generic.ipp" 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/map/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define MAP_T ::immer::map 12 | #include "generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/map/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using gc_memory = immer::memory_policy< 14 | immer::heap_policy, 15 | immer::no_refcount_policy, 16 | immer::gc_transience_policy, 17 | false>; 18 | 19 | template , 21 | typename Eq = std::equal_to> 22 | using test_map_t = immer::map; 23 | 24 | #define MAP_T test_map_t 25 | #include "generic.ipp" 26 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/map/issue-56.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // Thanks @dgel for reporting this issue 10 | // https://github.com/arximboldi/immer/issues/56 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | TEST_CASE("const map") 19 | { 20 | const auto x = immer::map{} 21 | .set("A", 1); 22 | auto it = x.begin(); 23 | CHECK(it->first == "A"); 24 | CHECK(it->second == 1); 25 | } 26 | 27 | TEST_CASE("const vector") 28 | { 29 | const auto x = immer::vector>{} 30 | .push_back({"A", 1}); 31 | auto it = x.begin(); 32 | CHECK(it->first == "A"); 33 | CHECK(it->second == 1); 34 | } 35 | 36 | TEST_CASE("const flex vector") 37 | { 38 | const auto x = immer::flex_vector>{} 39 | .push_back({"A", 1}); 40 | auto it = x.begin(); 41 | CHECK(it->first == "A"); 42 | CHECK(it->second == 1); 43 | } 44 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/set/B3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template , 13 | typename Eq = std::equal_to> 14 | using test_set_t = immer::set; 15 | 16 | #define SET_T test_set_t 17 | #include "generic.ipp" 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/set/B6.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template , 13 | typename Eq = std::equal_to> 14 | using test_set_t = immer::set; 15 | 16 | #define SET_T test_set_t 17 | #include "generic.ipp" 18 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/set/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define SET_T ::immer::set 12 | #include "generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/set/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using gc_memory = immer::memory_policy< 14 | immer::heap_policy, 15 | immer::no_refcount_policy, 16 | immer::gc_transience_policy, 17 | false>; 18 | 19 | template , 21 | typename Eq = std::equal_to> 22 | using test_set_t = immer::set; 23 | 24 | #define SET_T test_set_t 25 | #include "generic.ipp" 26 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/transient_tester.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #pragma once 10 | 11 | #include "dada.hpp" 12 | 13 | namespace { 14 | 15 | template 16 | struct transient_tester 17 | { 18 | VP vp; 19 | VT vt; 20 | dadaism d = {}; 21 | bool transient = false; 22 | 23 | transient_tester(VP vp) 24 | : vp{vp} 25 | , vt{vp.transient()} 26 | {} 27 | 28 | bool step() 29 | { 30 | auto s = d.next(); 31 | if (soft_dada()) { 32 | auto new_transient = !transient; 33 | try { 34 | if (new_transient) 35 | vt = vp.transient(); 36 | else 37 | vp = vt.persistent(); 38 | } catch (const dada_error&) { return false; } 39 | transient = new_transient; 40 | return true; 41 | } else 42 | return false; 43 | } 44 | }; 45 | 46 | template 47 | transient_tester 48 | as_transient_tester(VP p) 49 | { 50 | return { std::move(p) }; 51 | } 52 | 53 | } // anonymous namespace 54 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/B3-BL0.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template 12 | using test_vector_t = immer::vector; 13 | 14 | #define VECTOR_T test_vector_t 15 | #include "generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/B3-BL2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template 12 | using test_vector_t = immer::vector; 13 | 14 | #define VECTOR_T test_vector_t 15 | #include "generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/B3-BL3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template 12 | using test_vector_t = immer::vector; 13 | 14 | #define VECTOR_T test_vector_t 15 | #include "generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/B3-BL4.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | template 12 | using test_vector_t = immer::vector; 13 | 14 | #define VECTOR_T test_vector_t 15 | #include "generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | 11 | #define VECTOR_T ::immer::vector 12 | #include "generic.ipp" 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using gc_memory = immer::memory_policy< 14 | immer::heap_policy, 15 | immer::no_refcount_policy, 16 | immer::gc_transience_policy, 17 | false>; 18 | 19 | template 20 | using test_vector_t = immer::vector; 21 | 22 | #define VECTOR_T test_vector_t 23 | #include "generic.ipp" 24 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector/issue-46.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | // Thanks Guiguiprim for reporting this issue 10 | // https://github.com/arximboldi/immer/issues/46 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | TEST_CASE("operator==() may return bad result") 19 | { 20 | using bool_vec = immer::flex_vector; 21 | 22 | immer::vector v0; 23 | auto tv = v0.transient(); 24 | tv.push_back(bool_vec(9, false)); 25 | tv.push_back(bool_vec(10, false)); 26 | tv.push_back(bool_vec(8, false)); 27 | tv.push_back(bool_vec(6, false)); 28 | tv.push_back(bool_vec(9, false)); 29 | tv.push_back(bool_vec(7, false)); 30 | tv.push_back(bool_vec(8, false)); 31 | tv.push_back(bool_vec(9, false)); 32 | tv.push_back(bool_vec(10, false)); 33 | v0 = tv.persistent(); 34 | 35 | auto v1 = v0.update(1, [](bool_vec vec) { 36 | return vec.set(8, true); 37 | }); 38 | 39 | CHECK(v0[1] != v1[1]); 40 | CHECK(v0 != v1); 41 | } 42 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector_transient/B3-BL0.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | template 13 | using test_vector_t = immer::vector; 14 | 15 | template 16 | using test_vector_transient_t = typename test_vector_t::transient_type; 17 | 18 | #define VECTOR_T test_vector_t 19 | #define VECTOR_TRANSIENT_T test_vector_transient_t 20 | 21 | #include "generic.ipp" 22 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector_transient/default.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #define VECTOR_T ::immer::vector 13 | #define VECTOR_TRANSIENT_T ::immer::vector_transient 14 | 15 | #include "generic.ipp" 16 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/test/vector_transient/gc.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // immer: immutable data structures for C++ 3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente 4 | // 5 | // This software is distributed under the Boost Software License, Version 1.0. 6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | using gc_memory = immer::memory_policy< 16 | immer::heap_policy, 17 | immer::no_refcount_policy, 18 | immer::gc_transience_policy, 19 | false>; 20 | 21 | template 22 | using test_vector_t = immer::vector; 23 | 24 | template 25 | using test_vector_transient_t = immer::vector_transient; 26 | 27 | #define VECTOR_T test_vector_t 28 | #define VECTOR_TRANSIENT_T test_vector_transient_t 29 | 30 | #include "generic.ipp" 31 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/bin2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Unloved program to convert a binary on stdin to a C include on stdout 3 | * 4 | * Jan 1999 Matt Mackall 5 | * Jun 2017 Juan Pedro Bolivar Puente 6 | * 7 | * This software may be used and distributed according to the terms 8 | * of the GNU General Public License, incorporated herein by reference. 9 | */ 10 | 11 | #include 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | int ch, total = 0; 16 | 17 | if (argc > 1) 18 | printf("const std::uint8_t %s[] %s= {\n", 19 | argv[1], argc > 2 ? argv[2] : ""); 20 | 21 | do { 22 | while ((ch = getchar()) != EOF) { 23 | total++; 24 | printf("0x%02x,", ch); 25 | if (total % 16 == 0) 26 | break; 27 | } 28 | } while (ch != EOF); 29 | 30 | if (argc > 1) 31 | printf("\n};\nconst std::size_t %s_size = %d;\n", 32 | argv[1], total); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/clojure/README.md: -------------------------------------------------------------------------------- 1 | 2 | ``` 3 | lein run 4 | ``` 5 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/clojure/project.clj: -------------------------------------------------------------------------------- 1 | (defproject immer-benchmarks "0.1.0-SNAPSHOT" 2 | :description "Benchmarks for immutable data structures" 3 | :url "http://example.com/FIXME" 4 | :dependencies [[org.clojure/clojure "1.8.0"] 5 | [org.clojure/core.rrb-vector "0.0.11"] 6 | [criterium "0.4.4"]] 7 | :plugins [[lein-git-deps "0.0.1-SNAPSHOT"]] 8 | ;;:git-dependencies [["https://github.com/clojure/core.rrb-vector.git"]] 9 | :source-paths [;;".lein-git-deps/core.rrb-vector/src/main/clojure" 10 | "src"] 11 | 12 | :main immer-benchmark) 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/licensing-00-add-gpl3.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # https://github.com/osterman/copyright-header 4 | 5 | copyright-header \ 6 | --license GPL3 \ 7 | --copyright-software immer \ 8 | --copyright-software-description "immutable data structures for C++" \ 9 | --copyright-holder "Juan Pedro Bolivar Puente" \ 10 | --copyright-year 2016 \ 11 | -a . \ 12 | -o . 13 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/licensing-01-from-gpl3-to-lgpl3.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # https://github.com/osterman/copyright-header 4 | 5 | copyright-header \ 6 | --license GPL3 \ 7 | --copyright-software immer \ 8 | --copyright-software-description "immutable data structures for C++" \ 9 | --copyright-holder "Juan Pedro Bolivar Puente" \ 10 | --copyright-year 2016 \ 11 | --copyright-year 2017 \ 12 | -r . \ 13 | -o . 14 | 15 | copyright-header \ 16 | --license GPL3 \ 17 | --copyright-software immer \ 18 | --copyright-software-description "immutable data structures for C++" \ 19 | --copyright-holder "Juan Pedro Bolivar Puente" \ 20 | --copyright-year 2016 \ 21 | -r . \ 22 | -o . 23 | 24 | copyright-header \ 25 | --license GPL3 \ 26 | --copyright-software immer \ 27 | --copyright-software-description "immutable data structures for C++" \ 28 | --copyright-holder "Juan Pedro Bolivar Puente" \ 29 | --copyright-year 2017 \ 30 | -r . \ 31 | -o . 32 | 33 | copyright-header \ 34 | --license LGPL3 \ 35 | --copyright-software immer \ 36 | --copyright-software-description "immutable data structures for C++" \ 37 | --copyright-holder "Juan Pedro Bolivar Puente" \ 38 | --copyright-year 2016 \ 39 | --copyright-year 2017 \ 40 | -a . \ 41 | -o . 42 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/licensing-02-from-lgpl3-to-boost.bash: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | 4 | # https://github.com/osterman/copyright-header 5 | 6 | copyright-header \ 7 | --license LGPL3 \ 8 | --copyright-software immer \ 9 | --copyright-software-description "immutable data structures for C++" \ 10 | --copyright-holder "Juan Pedro Bolivar Puente" \ 11 | --copyright-year 2016 \ 12 | --copyright-year 2017 \ 13 | -r . \ 14 | -o . 15 | 16 | copyright-header \ 17 | --license-file Boost \ 18 | --copyright-software immer \ 19 | --copyright-software-description "immutable data structures for C++" \ 20 | --copyright-holder "Juan Pedro Bolivar Puente" \ 21 | --copyright-year 2016 \ 22 | --copyright-year 2017 \ 23 | --copyright-year 2018 \ 24 | -a . \ 25 | -o . 26 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/reproduce-paper-results.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | test -d build || mkdir -p build 4 | cd build 5 | 6 | cmake .. \ 7 | -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ 8 | -DCHECK_BENCHMARKS=1 \ 9 | -DBENCHMARK_PARAM="N:1000" -DBENCHMARK_SAMPLES="100" 10 | make benchmarks -j1 11 | ctest -R "benchmark/vector-paper*" 12 | 13 | cmake ..\ 14 | -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ 15 | -DCHECK_BENCHMARKS=1 \ 16 | -DBENCHMARK_PARAM="N:100000" -DBENCHMARK_SAMPLES="20" 17 | make benchmarks -j1 18 | ctest -R "benchmark/vector-paper*" 19 | 20 | cmake .. \ 21 | -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ 22 | -DCHECK_BENCHMARKS=1 \ 23 | -DBENCHMARK_PARAM="N:10000000" -DBENCHMARK_SAMPLES="3" 24 | make benchmarks -j1 25 | ctest -R "benchmark/vector-paper*" 26 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/scala/README.md: -------------------------------------------------------------------------------- 1 | 2 | ``` 3 | # sbt 4 | > test 5 | > test-only org.immer.* -- -verbose 6 | ``` 7 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/scala/build.sbt: -------------------------------------------------------------------------------- 1 | /** This is the simplest possible use of ScalaMeter. 2 | * It allows running ScalaMeter benchmarks as part of the test suite. 3 | * It means, that when the test command is run, ScalaMeter benchmarks are run along 4 | * the tests from other test frameworks, such as ScalaTest or ScalaCheck. 5 | */ 6 | lazy val basic = Project( 7 | "basic", 8 | file("."), 9 | settings = Defaults.coreDefaultSettings ++ Seq( 10 | name := "immer-bechmarks", 11 | organization := "org.immer", 12 | scalaVersion := "2.11.1", 13 | scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-Xlint"), 14 | publishArtifact := false, 15 | libraryDependencies ++= Seq( 16 | "com.storm-enroute" %% "scalameter" % "0.8.2" % "test", 17 | "io.github.nicolasstucki" %% "scala-rrb-vector" % "0.1.1" 18 | ), 19 | resolvers ++= Seq( 20 | "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots", 21 | "Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases" 22 | ), 23 | testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"), 24 | parallelExecution in Test := false, 25 | logBuffered := false 26 | ) 27 | ) 28 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/scala/version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "0.8.2" 2 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/travis/ssh-key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Functional-Programming-with-Cpp/64085205bbc052f8ee691b186fb7aa676904e196/Chapter10/immer-0.5.0/tools/travis/ssh-key.enc -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/travis/ssh-key.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBLgrMsYWwjiR/oe2bzg1kr1CGgLYiLrvQIeZw9mv10qF+MS+xpthy4tXxEHHeqkbQ1FsSoo3RaCKnya47LTysT1HE4Qf1TbxY5b1kU9SJ0jGNYejvkdmWzg/wspSCbFi3PGJhctxoks5sJCfVMc/oFwIlFAZALfL3JIRYk8EZv7bnrtA1Il1hPV2ug7ADBWJOXCc8pW4E7X3ZiDnvAZfqZ1QHrcQwy1aA8LVTv5azJg7Db8D90JjuRTlhO1XL7Cg/PGBkP1B3jOW5LRZK8AupnOPTw4kIsIc/i32O/poZPIRbHqYumYqEKBJQ/ggN4rKVXcp0lrMZ6/joslFLMvwr immer 2 | -------------------------------------------------------------------------------- /Chapter10/immer-0.5.0/tools/with-tee.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "${@:2} | tee $1" 4 | 5 | ${@:2} | tee $1 6 | -------------------------------------------------------------------------------- /Chapter10/immutableDataStructures.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 7 | #include "doctest.h" 8 | #include 9 | 10 | using namespace std; 11 | using namespace std::placeholders; 12 | 13 | TEST_CASE("Check immutable vector"){ 14 | const auto empty = immer::vector{}; 15 | const auto withOneElement = empty.push_back(42); 16 | 17 | CHECK_EQ(0, empty.size()); 18 | CHECK_EQ(1, withOneElement.size()); 19 | CHECK_EQ(42, withOneElement[0]); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Chapter10/runWithMemoryConsumptionMonitoring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | LOG_FILE=$1 4 | rm -f ./out/$1 5 | ./out/memoryOptimization& 6 | APP_PID=$! 7 | echo $APP_PID 8 | watch -e -n0.1 'grep VmSize /proc/'$APP_PID'/status >> ./out/'$LOG_FILE 9 | exit 0 10 | -------------------------------------------------------------------------------- /Chapter10/runWithThreadMonitoring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | LOG_FILE=$1 4 | rm -f ./out/$1 5 | ./out/asynchronousExecution& 6 | APP_PID=$! 7 | echo $APP_PID 8 | watch -e -n0.1 'grep Threads /proc/'$APP_PID'/status >> ./out/'$LOG_FILE 9 | exit 0 10 | -------------------------------------------------------------------------------- /Chapter11/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-o", 8 | "out/propertyBasedTests", 9 | "propertyBasedTests.cpp" 10 | ], 11 | "directory": "/home/alexb/work/bookCode/chapter12", 12 | "file": "propertyBasedTests.cpp" 13 | }, 14 | { 15 | "arguments": [ 16 | "c++", 17 | "-c", 18 | "-std=c++17", 19 | "-O3", 20 | "-Wall", 21 | "-Wextra", 22 | "-Werror", 23 | "-o", 24 | "out/exampleBasedTests", 25 | "exampleBasedTests.cpp" 26 | ], 27 | "directory": "/home/alexb/work/bookCode/chapter12", 28 | "file": "exampleBasedTests.cpp" 29 | } 30 | ] -------------------------------------------------------------------------------- /Chapter11/exampleBasedTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 8 | #include "doctest.h" 9 | 10 | using namespace std; 11 | using namespace std::placeholders; 12 | using namespace std::chrono; 13 | 14 | auto power = [](int first, int second){ 15 | return pow(first, second); 16 | }; 17 | 18 | int maxInt = numeric_limits::max(); 19 | 20 | TEST_CASE("Power"){ 21 | CHECK_EQ(1, power(0, 0)); 22 | CHECK_EQ(0, power(0, 1)); 23 | CHECK_EQ(0, power(0, maxInt)); 24 | CHECK_EQ(1, power(1, 1)); 25 | CHECK_EQ(1, power(1, 2)); 26 | CHECK_EQ(1, power(1, maxInt)); 27 | CHECK_EQ(1, power(2, 0)); 28 | CHECK_EQ(2, power(2, 1)); 29 | CHECK_EQ(4, power(2, 2)); 30 | CHECK_EQ(maxInt, power(2, 31) - 1); 31 | CHECK_EQ(1, power(3, 0)); 32 | CHECK_EQ(3, power(3, 1)); 33 | CHECK_EQ(9, power(3, 2)); 34 | CHECK_EQ(1, power(maxInt, 0)); 35 | CHECK_EQ(maxInt, power(maxInt, 1)); 36 | } 37 | 38 | TEST_CASE("1 raised to a power is 1"){ 39 | int exponent; 40 | 41 | SUBCASE("0"){ 42 | exponent = 0; 43 | } 44 | SUBCASE("1"){ 45 | exponent = 1; 46 | } 47 | SUBCASE("2"){ 48 | exponent = 1; 49 | } 50 | SUBCASE("maxInt"){ 51 | exponent = maxInt; 52 | } 53 | 54 | CAPTURE(exponent); 55 | CHECK_EQ(1, power(1, exponent)); 56 | } 57 | -------------------------------------------------------------------------------- /Chapter11/makefile: -------------------------------------------------------------------------------- 1 | all: exampleBasedTests propertyBasedTests 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | exampleBasedTests: .outputFolder 7 | g++ -std=c++17 -O3 exampleBasedTests.cpp -Wall -Wextra -Werror -o out/exampleBasedTests 8 | ./out/exampleBasedTests 9 | 10 | propertyBasedTests: .outputFolder 11 | g++ -std=c++17 propertyBasedTests.cpp -o out/propertyBasedTests 12 | ./out/propertyBasedTests 13 | -------------------------------------------------------------------------------- /Chapter12/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/write", 12 | "write.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter12", 15 | "file": "write.cpp" 16 | } 17 | ] -------------------------------------------------------------------------------- /Chapter12/computeSalariesRefactor/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "computeSalaries.h", 8 | "-Wall", 9 | "-Wextra", 10 | "-Werror", 11 | "-o", 12 | "out/computeSalariesTest", 13 | "computeSalariesTest.cpp" 14 | ], 15 | "directory": "/home/alexb/work/bookCode/chapter12/computeSalariesRefactor", 16 | "file": "computeSalariesTest.cpp" 17 | } 18 | ] -------------------------------------------------------------------------------- /Chapter12/computeSalariesRefactor/computeSalariesTest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Hands-On-Functional-Programming-with-Cpp/64085205bbc052f8ee691b186fb7aa676904e196/Chapter12/computeSalariesRefactor/computeSalariesTest -------------------------------------------------------------------------------- /Chapter12/computeSalariesRefactor/computeSalariesTest.cpp: -------------------------------------------------------------------------------- 1 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 2 | #include "doctest.h" 3 | #include "computeSalaries.h" 4 | 5 | using namespace std; 6 | 7 | TEST_CASE("Base salary"){ 8 | CHECK_EQ(1500, baseSalaryForPosition("Tester")); 9 | CHECK_EQ(1600, baseSalaryForPosition("Analyst")); 10 | CHECK_EQ(2000, baseSalaryForPosition("Developer")); 11 | CHECK_EQ(3000, baseSalaryForPosition("Team Leader")); 12 | CHECK_EQ(4000, baseSalaryForPosition("Manager")); 13 | CHECK_EQ(0, baseSalaryForPosition("asdfasdfs")); 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /Chapter12/computeSalariesRefactor/makefile: -------------------------------------------------------------------------------- 1 | all: computeSalaries computeSalariesTest 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | computeSalaries: .outputFolder 7 | g++ -std=c++17 computeSalaries.cpp computeSalaries.h -Wall -Wextra -Werror -o out/computeSalaries 8 | ./out/computeSalaries 9 | 10 | computeSalariesTest: .outputFolder 11 | g++ -std=c++17 computeSalariesTest.cpp computeSalaries.h -Wall -Wextra -Werror -o out/computeSalariesTest 12 | ./out/computeSalariesTest 13 | -------------------------------------------------------------------------------- /Chapter12/makefile: -------------------------------------------------------------------------------- 1 | all: computeSalaries strategy dependencyinjection autoincrement state maybe 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | computeSalaries: .outputFolder 7 | g++ -std=c++17 computeSalaries.cpp -Wall -Wextra -Werror -o out/computeSalaries 8 | ./out/computeSalaries 9 | 10 | strategy : .outputFolder 11 | g++ -std=c++17 strategy.cpp -Wall -Wextra -Werror -o out/strategy 12 | ./out/strategy 13 | 14 | dependencyinjection : .outputFolder 15 | g++ -std=c++17 dependencyinjection.cpp -Wall -Wextra -Werror -o out/dependencyinjection 16 | ./out/dependencyinjection 17 | 18 | autoincrement: .outputFolder 19 | g++ -std=c++17 autoincrement.cpp -Wall -Wextra -Werror -o out/autoincrement 20 | ./out/autoincrement 21 | 22 | state: .outputFolder 23 | g++ -std=c++17 state.cpp -Wall -Wextra -Werror -o out/state 24 | ./out/state 25 | 26 | maybe: .outputFolder 27 | g++ -std=c++17 maybe.cpp -Wall -Wextra -Werror -o out/maybe 28 | ./out/maybe 29 | -------------------------------------------------------------------------------- /Chapter12/numbers.txt: -------------------------------------------------------------------------------- 1 | 10 2 | 20 3 | -------------------------------------------------------------------------------- /Chapter13/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Wall", 8 | "-Wextra", 9 | "-Werror", 10 | "-o", 11 | "out/twitter", 12 | "twitter.cpp" 13 | ], 14 | "directory": "/home/alexb/work/bookCode/chapter13", 15 | "file": "twitter.cpp" 16 | } 17 | ] -------------------------------------------------------------------------------- /Chapter13/makefile: -------------------------------------------------------------------------------- 1 | all: twitter 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | twitter: .outputFolder 7 | g++ -std=c++17 twitter.cpp -Wall -Wextra -Werror -o out/twitter 8 | ./out/twitter 9 | -------------------------------------------------------------------------------- /Chapter14/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Iinclude/", 8 | "-Wall", 9 | "-Wextra", 10 | "-Werror", 11 | "-o", 12 | "out/ranges", 13 | "ranges.cpp" 14 | ], 15 | "directory": "/home/alexb/work/bookCode/chapter14", 16 | "file": "ranges.cpp" 17 | } 18 | ] -------------------------------------------------------------------------------- /Chapter14/include/module.modulemap: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Gonzalo Brito Gadeschi 2017. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | module meta { 15 | umbrella "meta" 16 | export * 17 | } 18 | module range_v3 { 19 | umbrella "range" 20 | export * 21 | } 22 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/action.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ACTION_HPP 15 | #define RANGES_V3_ACTION_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/algorithm/tagspec.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_ALGORITHM_TAGSPEC_HPP 14 | #define RANGES_V3_ALGORITHM_TAGSPEC_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | RANGES_DEFINE_TAG_SPECIFIER(in) 24 | RANGES_DEFINE_TAG_SPECIFIER(in1) 25 | RANGES_DEFINE_TAG_SPECIFIER(in2) 26 | RANGES_DEFINE_TAG_SPECIFIER(out) 27 | RANGES_DEFINE_TAG_SPECIFIER(out1) 28 | RANGES_DEFINE_TAG_SPECIFIER(out2) 29 | RANGES_DEFINE_TAG_SPECIFIER(fun) 30 | RANGES_DEFINE_TAG_SPECIFIER(min) 31 | RANGES_DEFINE_TAG_SPECIFIER(max) 32 | RANGES_DEFINE_TAG_SPECIFIER(begin) 33 | RANGES_DEFINE_TAG_SPECIFIER(end) 34 | 35 | RANGES_DEFINE_TAG_SPECIFIER(current) 36 | RANGES_DEFINE_TAG_SPECIFIER(engine) 37 | RANGES_DEFINE_TAG_SPECIFIER(range) 38 | RANGES_DEFINE_TAG_SPECIFIER(size) 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/all.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ALL_HPP 15 | #define RANGES_V3_ALL_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/back.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_BACK_HPP 15 | #define RANGES_V3_BACK_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace ranges 25 | { 26 | inline namespace v3 27 | { 28 | /// \ingroup group-core 29 | struct back_fn 30 | { 31 | /// \return `*prev(end(rng))` 32 | template() && BidirectionalRange())> 34 | RANGES_CXX14_CONSTEXPR 35 | range_reference_t operator()(Rng &&rng) const 36 | { 37 | return *prev(end(rng)); 38 | } 39 | }; 40 | 41 | /// \ingroup group-core 42 | /// \sa `back_fn` 43 | RANGES_INLINE_VARIABLE(back_fn, back) 44 | } 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/core.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_CORE_HPP 15 | #define RANGES_V3_CORE_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/detail/adl_get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Casey Carter 2018 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_DETAIL_ADL_GET_HPP 14 | #define RANGES_V3_DETAIL_ADL_GET_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | namespace detail 24 | { 25 | namespace _adl_get_ 26 | { 27 | template void get(); 28 | 29 | template 30 | constexpr auto adl_get(Tuple &&t) 31 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 32 | ( 33 | get(static_cast(t)) 34 | ) 35 | 36 | template 37 | constexpr auto adl_get(Tuple &&t) 38 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 39 | ( 40 | get(static_cast(t)) 41 | ) 42 | } 43 | using _adl_get_::adl_get; 44 | } 45 | } 46 | } 47 | 48 | #endif // RANGES_V3_DETAIL_ADL_GET_HPP 49 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/front.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_FRONT_HPP 15 | #define RANGES_V3_FRONT_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace ranges 24 | { 25 | inline namespace v3 26 | { 27 | /// \ingroup group-core 28 | struct front_fn 29 | { 30 | /// \return `*begin(rng)` 31 | template())> 33 | constexpr range_reference_t operator()(Rng &&rng) const 34 | { 35 | return *begin(rng); 36 | } 37 | }; 38 | 39 | /// \ingroup group-core 40 | /// \sa `front_fn` 41 | RANGES_INLINE_VARIABLE(front_fn, front) 42 | } 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/numeric.hpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | /// \file numeric.hpp 3 | /// Contains range-based versions of the numeric algorithms 4 | // 5 | // Copyright Eric Niebler 2014-present 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See 8 | // accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | 11 | #ifndef RANGES_V3_NUMERIC_HPP 12 | #define RANGES_V3_NUMERIC_HPP 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/utility/get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_GET_HPP 15 | #define RANGES_V3_UTILITY_GET_HPP 16 | 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | /// \addtogroup group-utility Utility 25 | /// @{ 26 | /// 27 | template 28 | T & get(meta::id_t & value) 29 | { 30 | return value; 31 | } 32 | 33 | template 34 | T const & get(meta::id_t const & value) 35 | { 36 | return value; 37 | } 38 | 39 | template 40 | T && get(meta::id_t && value) 41 | { 42 | return std::move(value); 43 | } 44 | /// @} 45 | } 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/utility/nullptr_v.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_NULLVAL_HPP 15 | #define RANGES_V3_UTILITY_NULLVAL_HPP 16 | 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | /// \ingroup group-utility 24 | template 25 | constexpr T *_nullptr_v() 26 | { 27 | return nullptr; 28 | } 29 | 30 | #if RANGES_CXX_VARIABLE_TEMPLATES 31 | /// \ingroup group-utility 32 | template 33 | constexpr T *nullptr_v = nullptr; 34 | #endif 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/utility/static_const.hpp: -------------------------------------------------------------------------------- 1 | // Range v3 library 2 | // 3 | // Copyright Eric Niebler 2013-present 4 | // 5 | // Use, modification and distribution is subject to the 6 | // Boost Software License, Version 1.0. (See accompanying 7 | // file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // Project home: https://github.com/ericniebler/range-v3 11 | // 12 | 13 | #ifndef RANGES_V3_UTILITY_STATIC_CONST_HPP 14 | #define RANGES_V3_UTILITY_STATIC_CONST_HPP 15 | 16 | #include 17 | 18 | namespace ranges 19 | { 20 | inline namespace v3 21 | { 22 | /// \ingroup group-utility 23 | 24 | template 25 | struct static_const 26 | { 27 | static constexpr T value {}; 28 | }; 29 | 30 | /// \ingroup group-utility 31 | /// \sa `static_const` 32 | template 33 | constexpr T static_const::value; 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/utility/tagged_tuple.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 14 | #define RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | template 25 | using tagged_tuple = 26 | tagged...>, detail::tag_spec...>; 27 | 28 | template 29 | constexpr tagged_tuple)...> 30 | make_tagged_tuple(Ts &&... ts) 31 | { 32 | return tagged_tuple)...>{static_cast(ts)...}; 33 | } 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/version.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2017-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VERSION_HPP 15 | #define RANGES_V3_VERSION_HPP 16 | 17 | #define RANGE_V3_MAJOR 0 18 | #define RANGE_V3_MINOR 5 19 | #define RANGE_V3_PATCHLEVEL 0 20 | 21 | #define RANGE_V3_VERSION (RANGE_V3_MAJOR * 10000 \ 22 | + RANGE_V3_MINOR * 100 \ 23 | + RANGE_V3_PATCHLEVEL) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Chapter14/include/range/v3/view/filter.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VIEW_FILTER_HPP 15 | #define RANGES_V3_VIEW_FILTER_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace ranges 23 | { 24 | inline namespace v3 25 | { 26 | namespace view 27 | { 28 | /// Given a source range, unary predicate, and optional projection, 29 | /// present a view of the elements that satisfy the predicate. 30 | using filter_fn = remove_if_fn_; 31 | 32 | /// \relates filter_fn 33 | /// \ingroup group-views 34 | RANGES_INLINE_VARIABLE(view, filter) 35 | } 36 | } 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter14/makefile: -------------------------------------------------------------------------------- 1 | all: ranges 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | ranges: .outputFolder 7 | g++ -std=c++17 -Iinclude/ ranges.cpp -Wall -Wextra -Werror -o out/ranges 8 | ./out/ranges 9 | -------------------------------------------------------------------------------- /Chapter15/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++17", 7 | "-Iinclude/", 8 | "-Wall", 9 | "-Wextra", 10 | "-Werror", 11 | "-o", 12 | "out/functional", 13 | "functional.cpp" 14 | ], 15 | "directory": "/home/alexb/work/bookCode/chapter15", 16 | "file": "functional.cpp" 17 | }, 18 | { 19 | "arguments": [ 20 | "c++", 21 | "-c", 22 | "-std=c++17", 23 | "-Iinclude/", 24 | "-Wall", 25 | "-Wextra", 26 | "-Werror", 27 | "-o", 28 | "out/algorithm", 29 | "algorithm.cpp" 30 | ], 31 | "directory": "/home/alexb/work/bookCode/chapter15", 32 | "file": "algorithm.cpp" 33 | } 34 | ] -------------------------------------------------------------------------------- /Chapter15/include/module.modulemap: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Gonzalo Brito Gadeschi 2017. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | module meta { 15 | umbrella "meta" 16 | export * 17 | } 18 | module range_v3 { 19 | umbrella "range" 20 | export * 21 | } 22 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/action.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ACTION_HPP 15 | #define RANGES_V3_ACTION_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/algorithm/tagspec.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_ALGORITHM_TAGSPEC_HPP 14 | #define RANGES_V3_ALGORITHM_TAGSPEC_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | RANGES_DEFINE_TAG_SPECIFIER(in) 24 | RANGES_DEFINE_TAG_SPECIFIER(in1) 25 | RANGES_DEFINE_TAG_SPECIFIER(in2) 26 | RANGES_DEFINE_TAG_SPECIFIER(out) 27 | RANGES_DEFINE_TAG_SPECIFIER(out1) 28 | RANGES_DEFINE_TAG_SPECIFIER(out2) 29 | RANGES_DEFINE_TAG_SPECIFIER(fun) 30 | RANGES_DEFINE_TAG_SPECIFIER(min) 31 | RANGES_DEFINE_TAG_SPECIFIER(max) 32 | RANGES_DEFINE_TAG_SPECIFIER(begin) 33 | RANGES_DEFINE_TAG_SPECIFIER(end) 34 | 35 | RANGES_DEFINE_TAG_SPECIFIER(current) 36 | RANGES_DEFINE_TAG_SPECIFIER(engine) 37 | RANGES_DEFINE_TAG_SPECIFIER(range) 38 | RANGES_DEFINE_TAG_SPECIFIER(size) 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/all.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ALL_HPP 15 | #define RANGES_V3_ALL_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/back.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_BACK_HPP 15 | #define RANGES_V3_BACK_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace ranges 25 | { 26 | inline namespace v3 27 | { 28 | /// \ingroup group-core 29 | struct back_fn 30 | { 31 | /// \return `*prev(end(rng))` 32 | template() && BidirectionalRange())> 34 | RANGES_CXX14_CONSTEXPR 35 | range_reference_t operator()(Rng &&rng) const 36 | { 37 | return *prev(end(rng)); 38 | } 39 | }; 40 | 41 | /// \ingroup group-core 42 | /// \sa `back_fn` 43 | RANGES_INLINE_VARIABLE(back_fn, back) 44 | } 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/core.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_CORE_HPP 15 | #define RANGES_V3_CORE_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/detail/adl_get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Casey Carter 2018 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_DETAIL_ADL_GET_HPP 14 | #define RANGES_V3_DETAIL_ADL_GET_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | namespace detail 24 | { 25 | namespace _adl_get_ 26 | { 27 | template void get(); 28 | 29 | template 30 | constexpr auto adl_get(Tuple &&t) 31 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 32 | ( 33 | get(static_cast(t)) 34 | ) 35 | 36 | template 37 | constexpr auto adl_get(Tuple &&t) 38 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 39 | ( 40 | get(static_cast(t)) 41 | ) 42 | } 43 | using _adl_get_::adl_get; 44 | } 45 | } 46 | } 47 | 48 | #endif // RANGES_V3_DETAIL_ADL_GET_HPP 49 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/front.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_FRONT_HPP 15 | #define RANGES_V3_FRONT_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace ranges 24 | { 25 | inline namespace v3 26 | { 27 | /// \ingroup group-core 28 | struct front_fn 29 | { 30 | /// \return `*begin(rng)` 31 | template())> 33 | constexpr range_reference_t operator()(Rng &&rng) const 34 | { 35 | return *begin(rng); 36 | } 37 | }; 38 | 39 | /// \ingroup group-core 40 | /// \sa `front_fn` 41 | RANGES_INLINE_VARIABLE(front_fn, front) 42 | } 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/numeric.hpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | /// \file numeric.hpp 3 | /// Contains range-based versions of the numeric algorithms 4 | // 5 | // Copyright Eric Niebler 2014-present 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See 8 | // accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | 11 | #ifndef RANGES_V3_NUMERIC_HPP 12 | #define RANGES_V3_NUMERIC_HPP 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/utility/get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_GET_HPP 15 | #define RANGES_V3_UTILITY_GET_HPP 16 | 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | /// \addtogroup group-utility Utility 25 | /// @{ 26 | /// 27 | template 28 | T & get(meta::id_t & value) 29 | { 30 | return value; 31 | } 32 | 33 | template 34 | T const & get(meta::id_t const & value) 35 | { 36 | return value; 37 | } 38 | 39 | template 40 | T && get(meta::id_t && value) 41 | { 42 | return std::move(value); 43 | } 44 | /// @} 45 | } 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/utility/nullptr_v.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_NULLVAL_HPP 15 | #define RANGES_V3_UTILITY_NULLVAL_HPP 16 | 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | /// \ingroup group-utility 24 | template 25 | constexpr T *_nullptr_v() 26 | { 27 | return nullptr; 28 | } 29 | 30 | #if RANGES_CXX_VARIABLE_TEMPLATES 31 | /// \ingroup group-utility 32 | template 33 | constexpr T *nullptr_v = nullptr; 34 | #endif 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/utility/static_const.hpp: -------------------------------------------------------------------------------- 1 | // Range v3 library 2 | // 3 | // Copyright Eric Niebler 2013-present 4 | // 5 | // Use, modification and distribution is subject to the 6 | // Boost Software License, Version 1.0. (See accompanying 7 | // file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // Project home: https://github.com/ericniebler/range-v3 11 | // 12 | 13 | #ifndef RANGES_V3_UTILITY_STATIC_CONST_HPP 14 | #define RANGES_V3_UTILITY_STATIC_CONST_HPP 15 | 16 | #include 17 | 18 | namespace ranges 19 | { 20 | inline namespace v3 21 | { 22 | /// \ingroup group-utility 23 | 24 | template 25 | struct static_const 26 | { 27 | static constexpr T value {}; 28 | }; 29 | 30 | /// \ingroup group-utility 31 | /// \sa `static_const` 32 | template 33 | constexpr T static_const::value; 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/utility/tagged_tuple.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 14 | #define RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | template 25 | using tagged_tuple = 26 | tagged...>, detail::tag_spec...>; 27 | 28 | template 29 | constexpr tagged_tuple)...> 30 | make_tagged_tuple(Ts &&... ts) 31 | { 32 | return tagged_tuple)...>{static_cast(ts)...}; 33 | } 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/version.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2017-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VERSION_HPP 15 | #define RANGES_V3_VERSION_HPP 16 | 17 | #define RANGE_V3_MAJOR 0 18 | #define RANGE_V3_MINOR 5 19 | #define RANGE_V3_PATCHLEVEL 0 20 | 21 | #define RANGE_V3_VERSION (RANGE_V3_MAJOR * 10000 \ 22 | + RANGE_V3_MINOR * 100 \ 23 | + RANGE_V3_PATCHLEVEL) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Chapter15/include/range/v3/view/filter.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VIEW_FILTER_HPP 15 | #define RANGES_V3_VIEW_FILTER_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace ranges 23 | { 24 | inline namespace v3 25 | { 26 | namespace view 27 | { 28 | /// Given a source range, unary predicate, and optional projection, 29 | /// present a view of the elements that satisfy the predicate. 30 | using filter_fn = remove_if_fn_; 31 | 32 | /// \relates filter_fn 33 | /// \ingroup group-views 34 | RANGES_INLINE_VARIABLE(view, filter) 35 | } 36 | } 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter15/makefile: -------------------------------------------------------------------------------- 1 | all: functional algorithm 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | functional: .outputFolder 7 | g++ -std=c++17 -Iinclude/ functional.cpp -Wall -Wextra -Werror -o out/functional 8 | ./out/functional 9 | 10 | algorithm: .outputFolder 11 | g++ -std=c++17 -Iinclude/ algorithm.cpp -Wall -Wextra -Werror -o out/algorithm 12 | ./out/algorithm 13 | -------------------------------------------------------------------------------- /Chapter16/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "arguments": [ 4 | "c++", 5 | "-c", 6 | "-std=c++2a", 7 | "-Iinclude/", 8 | "-Wall", 9 | "-Wextra", 10 | "-Werror", 11 | "-o", 12 | "out/lambdas", 13 | "lambdas.cpp" 14 | ], 15 | "directory": "/home/alexb/work/bookCode/chapter16", 16 | "file": "lambdas.cpp" 17 | }, 18 | { 19 | "arguments": [ 20 | "c++", 21 | "-c", 22 | "-std=c++2a", 23 | "-Iinclude/", 24 | "-Wall", 25 | "-Wextra", 26 | "-Werror", 27 | "-o", 28 | "out/partialApplication", 29 | "partialApplication.cpp" 30 | ], 31 | "directory": "/home/alexb/work/bookCode/chapter16", 32 | "file": "partialApplication.cpp" 33 | } 34 | ] -------------------------------------------------------------------------------- /Chapter16/functionalComposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 8 | #include "doctest.h" 9 | #include 10 | 11 | using namespace std; 12 | using namespace std::placeholders; 13 | 14 | auto powerOf2 = [](const int exponent){ 15 | return pow(2, exponent); 16 | }; 17 | 18 | auto increment = [](const int value){ 19 | return value + 1; 20 | }; 21 | 22 | TEST_CASE("Composition"){ 23 | auto incrementPowerOf2 = [](const int exponent){ 24 | return increment(powerOf2(exponent)); 25 | }; 26 | 27 | CHECK_EQ(9, incrementPowerOf2(3)); 28 | } 29 | 30 | namespace Functions{ 31 | int incrementPowerOf2(const int exponent){ 32 | return increment(powerOf2(exponent)); 33 | }; 34 | } 35 | 36 | TEST_CASE("Composition"){ 37 | CHECK_EQ(9, Functions::incrementPowerOf2(3)); 38 | } 39 | 40 | template 41 | auto compose(F f, G g){ 42 | return [=](auto value){return f(g(value));}; 43 | } 44 | 45 | TEST_CASE("Composition"){ 46 | auto incrementPowerOf2 = compose(increment, powerOf2); 47 | 48 | CHECK_EQ(9, incrementPowerOf2(3)); 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /Chapter16/include/module.modulemap: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Gonzalo Brito Gadeschi 2017. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | module meta { 15 | umbrella "meta" 16 | export * 17 | } 18 | module range_v3 { 19 | umbrella "range" 20 | export * 21 | } 22 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/action.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ACTION_HPP 15 | #define RANGES_V3_ACTION_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/algorithm/tagspec.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_ALGORITHM_TAGSPEC_HPP 14 | #define RANGES_V3_ALGORITHM_TAGSPEC_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | RANGES_DEFINE_TAG_SPECIFIER(in) 24 | RANGES_DEFINE_TAG_SPECIFIER(in1) 25 | RANGES_DEFINE_TAG_SPECIFIER(in2) 26 | RANGES_DEFINE_TAG_SPECIFIER(out) 27 | RANGES_DEFINE_TAG_SPECIFIER(out1) 28 | RANGES_DEFINE_TAG_SPECIFIER(out2) 29 | RANGES_DEFINE_TAG_SPECIFIER(fun) 30 | RANGES_DEFINE_TAG_SPECIFIER(min) 31 | RANGES_DEFINE_TAG_SPECIFIER(max) 32 | RANGES_DEFINE_TAG_SPECIFIER(begin) 33 | RANGES_DEFINE_TAG_SPECIFIER(end) 34 | 35 | RANGES_DEFINE_TAG_SPECIFIER(current) 36 | RANGES_DEFINE_TAG_SPECIFIER(engine) 37 | RANGES_DEFINE_TAG_SPECIFIER(range) 38 | RANGES_DEFINE_TAG_SPECIFIER(size) 39 | } 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/all.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_ALL_HPP 15 | #define RANGES_V3_ALL_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/back.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_BACK_HPP 15 | #define RANGES_V3_BACK_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace ranges 25 | { 26 | inline namespace v3 27 | { 28 | /// \ingroup group-core 29 | struct back_fn 30 | { 31 | /// \return `*prev(end(rng))` 32 | template() && BidirectionalRange())> 34 | RANGES_CXX14_CONSTEXPR 35 | range_reference_t operator()(Rng &&rng) const 36 | { 37 | return *prev(end(rng)); 38 | } 39 | }; 40 | 41 | /// \ingroup group-core 42 | /// \sa `back_fn` 43 | RANGES_INLINE_VARIABLE(back_fn, back) 44 | } 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/core.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_CORE_HPP 15 | #define RANGES_V3_CORE_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/detail/adl_get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Casey Carter 2018 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_DETAIL_ADL_GET_HPP 14 | #define RANGES_V3_DETAIL_ADL_GET_HPP 15 | 16 | #include 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | namespace detail 24 | { 25 | namespace _adl_get_ 26 | { 27 | template void get(); 28 | 29 | template 30 | constexpr auto adl_get(Tuple &&t) 31 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 32 | ( 33 | get(static_cast(t)) 34 | ) 35 | 36 | template 37 | constexpr auto adl_get(Tuple &&t) 38 | RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT 39 | ( 40 | get(static_cast(t)) 41 | ) 42 | } 43 | using _adl_get_::adl_get; 44 | } 45 | } 46 | } 47 | 48 | #endif // RANGES_V3_DETAIL_ADL_GET_HPP 49 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/front.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2014-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_FRONT_HPP 15 | #define RANGES_V3_FRONT_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace ranges 24 | { 25 | inline namespace v3 26 | { 27 | /// \ingroup group-core 28 | struct front_fn 29 | { 30 | /// \return `*begin(rng)` 31 | template())> 33 | constexpr range_reference_t operator()(Rng &&rng) const 34 | { 35 | return *begin(rng); 36 | } 37 | }; 38 | 39 | /// \ingroup group-core 40 | /// \sa `front_fn` 41 | RANGES_INLINE_VARIABLE(front_fn, front) 42 | } 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/numeric.hpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | /// \file numeric.hpp 3 | /// Contains range-based versions of the numeric algorithms 4 | // 5 | // Copyright Eric Niebler 2014-present 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See 8 | // accompanying file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | 11 | #ifndef RANGES_V3_NUMERIC_HPP 12 | #define RANGES_V3_NUMERIC_HPP 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/utility/get.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_GET_HPP 15 | #define RANGES_V3_UTILITY_GET_HPP 16 | 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | /// \addtogroup group-utility Utility 25 | /// @{ 26 | /// 27 | template 28 | T & get(meta::id_t & value) 29 | { 30 | return value; 31 | } 32 | 33 | template 34 | T const & get(meta::id_t const & value) 35 | { 36 | return value; 37 | } 38 | 39 | template 40 | T && get(meta::id_t && value) 41 | { 42 | return std::move(value); 43 | } 44 | /// @} 45 | } 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/utility/nullptr_v.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013,2014. 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_UTILITY_NULLVAL_HPP 15 | #define RANGES_V3_UTILITY_NULLVAL_HPP 16 | 17 | #include 18 | 19 | namespace ranges 20 | { 21 | inline namespace v3 22 | { 23 | /// \ingroup group-utility 24 | template 25 | constexpr T *_nullptr_v() 26 | { 27 | return nullptr; 28 | } 29 | 30 | #if RANGES_CXX_VARIABLE_TEMPLATES 31 | /// \ingroup group-utility 32 | template 33 | constexpr T *nullptr_v = nullptr; 34 | #endif 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/utility/static_const.hpp: -------------------------------------------------------------------------------- 1 | // Range v3 library 2 | // 3 | // Copyright Eric Niebler 2013-present 4 | // 5 | // Use, modification and distribution is subject to the 6 | // Boost Software License, Version 1.0. (See accompanying 7 | // file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | // Project home: https://github.com/ericniebler/range-v3 11 | // 12 | 13 | #ifndef RANGES_V3_UTILITY_STATIC_CONST_HPP 14 | #define RANGES_V3_UTILITY_STATIC_CONST_HPP 15 | 16 | #include 17 | 18 | namespace ranges 19 | { 20 | inline namespace v3 21 | { 22 | /// \ingroup group-utility 23 | 24 | template 25 | struct static_const 26 | { 27 | static constexpr T value {}; 28 | }; 29 | 30 | /// \ingroup group-utility 31 | /// \sa `static_const` 32 | template 33 | constexpr T static_const::value; 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/utility/tagged_tuple.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | 13 | #ifndef RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 14 | #define RANGES_V3_UTILITY_TAGGED_TUPLE_HPP 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace ranges 21 | { 22 | inline namespace v3 23 | { 24 | template 25 | using tagged_tuple = 26 | tagged...>, detail::tag_spec...>; 27 | 28 | template 29 | constexpr tagged_tuple)...> 30 | make_tagged_tuple(Ts &&... ts) 31 | { 32 | return tagged_tuple)...>{static_cast(ts)...}; 33 | } 34 | } 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/version.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2017-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VERSION_HPP 15 | #define RANGES_V3_VERSION_HPP 16 | 17 | #define RANGE_V3_MAJOR 0 18 | #define RANGE_V3_MINOR 5 19 | #define RANGE_V3_PATCHLEVEL 0 20 | 21 | #define RANGE_V3_VERSION (RANGE_V3_MAJOR * 10000 \ 22 | + RANGE_V3_MINOR * 100 \ 23 | + RANGE_V3_PATCHLEVEL) 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Chapter16/include/range/v3/view/filter.hpp: -------------------------------------------------------------------------------- 1 | /// \file 2 | // Range v3 library 3 | // 4 | // Copyright Eric Niebler 2013-present 5 | // 6 | // Use, modification and distribution is subject to the 7 | // Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at 9 | // http://www.boost.org/LICENSE_1_0.txt) 10 | // 11 | // Project home: https://github.com/ericniebler/range-v3 12 | // 13 | 14 | #ifndef RANGES_V3_VIEW_FILTER_HPP 15 | #define RANGES_V3_VIEW_FILTER_HPP 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace ranges 23 | { 24 | inline namespace v3 25 | { 26 | namespace view 27 | { 28 | /// Given a source range, unary predicate, and optional projection, 29 | /// present a view of the elements that satisfy the predicate. 30 | using filter_fn = remove_if_fn_; 31 | 32 | /// \relates filter_fn 33 | /// \ingroup group-views 34 | RANGES_INLINE_VARIABLE(view, filter) 35 | } 36 | } 37 | } 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter16/makefile: -------------------------------------------------------------------------------- 1 | all: lambdas partialApplication functionalComposition 2 | 3 | .outputFolder: 4 | mkdir -p out 5 | 6 | lambdas: .outputFolder 7 | g++-8 -std=c++2a -Iinclude/ lambdas.cpp -Wall -Wextra -Werror -o out/lambdas 8 | ./out/lambdas 9 | 10 | partialApplication: .outputFolder 11 | g++-8 -std=c++2a -Iinclude/ partialApplication.cpp -Wall -Wextra -Werror -o out/partialApplication 12 | ./out/partialApplication 13 | 14 | functionalComposition: .outputFolder 15 | g++-8 -std=c++2a -Iinclude/ functionalComposition.cpp -Wall -Wextra -Werror -o out/functionalComposition 16 | ./out/functionalComposition 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # The code for this repository is under development :construction_worker: 5 | ### Download a free PDF 6 | 7 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
8 |

https://packt.link/free-ebook/9781789807332

--------------------------------------------------------------------------------