Full Code of orxfun/orx-parallel for AI

main 5c2da2eb39ca cached
341 files
1.1 MB
320.1k tokens
2306 symbols
1 requests
Download .txt
Showing preview only (1,249K chars total). Download the full file or copy to clipboard to get everything.
Repository: orxfun/orx-parallel
Branch: main
Commit: 5c2da2eb39ca
Files: 341
Total size: 1.1 MB

Directory structure:
gitextract_lozyb1bf/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .scripts/
│   ├── run_benchmark.sh
│   └── run_benchmarks.sh
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches/
│   ├── chain3_collect_map.rs
│   ├── chain4_collect_map.rs
│   ├── chain_collect_map.rs
│   ├── collect_filter.rs
│   ├── collect_filtermap.rs
│   ├── collect_flatmap.rs
│   ├── collect_iter_into_par.rs
│   ├── collect_long_chain.rs
│   ├── collect_map.rs
│   ├── collect_map_filter.rs
│   ├── collect_map_filter_hash_set.rs
│   ├── count_filtermap.rs
│   ├── count_flatmap.rs
│   ├── count_map.rs
│   ├── count_map_filter.rs
│   ├── drain_vec_collect_map_filter.rs
│   ├── find.rs
│   ├── find_any.rs
│   ├── find_flatmap.rs
│   ├── find_iter_into_par.rs
│   ├── find_map_filter.rs
│   ├── mut_for_each_iter.rs
│   ├── mut_for_each_slice.rs
│   ├── rec_iter_map_collect.rs
│   ├── rec_iter_map_sum.rs
│   ├── reduce.rs
│   ├── reduce_iter_into_par.rs
│   ├── reduce_long_chain.rs
│   ├── reduce_map.rs
│   ├── reduce_map_filter.rs
│   ├── result_collect_map.rs
│   ├── result_reduce_map.rs
│   ├── results/
│   │   └── benchmark-results.xlsx
│   ├── sum.rs
│   ├── sum_filtermap.rs
│   ├── sum_flatmap.rs
│   ├── sum_map_filter.rs
│   ├── t_par_merge_sorted.rs
│   ├── t_seq_merge_sorted.rs
│   ├── vec_deque_collect_map_filter.rs
│   └── vec_deque_collect_map_filter_owned.rs
├── docs/
│   └── using.md
├── examples/
│   ├── benchmark_collect.rs
│   ├── benchmark_find.rs
│   ├── benchmark_find_any.rs
│   ├── benchmark_heterogeneous.rs
│   ├── benchmark_pools.rs
│   ├── benchmark_reduce.rs
│   ├── collection_of_results.rs
│   ├── function_composition_with_mut_using.rs
│   ├── map_while.rs
│   ├── max_num_threads_config.rs
│   ├── mutable_par_iter.rs
│   ├── par_merge_sorted.rs
│   ├── parallelization_on_tree/
│   │   ├── collection_on_entire_tree.rs
│   │   ├── main.rs
│   │   ├── node.rs
│   │   ├── reduction_on_entire_tree.rs
│   │   ├── reduction_on_subset_of_tree.rs
│   │   ├── run_utils.rs
│   │   └── tree.rs
│   ├── using_for_each.rs
│   ├── using_map.rs
│   ├── using_metrics.rs
│   ├── using_random_walk.rs
│   └── utils/
│       ├── benchmark_utils.rs
│       └── mod.rs
├── src/
│   ├── collect_into/
│   │   ├── collect.rs
│   │   ├── fixed_vec.rs
│   │   ├── mod.rs
│   │   ├── par_collect_into.rs
│   │   ├── split_vec.rs
│   │   ├── utils.rs
│   │   └── vec.rs
│   ├── computational_variants/
│   │   ├── fallible_option.rs
│   │   ├── fallible_result/
│   │   │   ├── map_result.rs
│   │   │   ├── mod.rs
│   │   │   ├── par_result.rs
│   │   │   └── xap_result.rs
│   │   ├── map.rs
│   │   ├── mod.rs
│   │   ├── par.rs
│   │   ├── tests/
│   │   │   ├── copied.rs
│   │   │   ├── count.rs
│   │   │   ├── enumerate.rs
│   │   │   ├── fallible_option.rs
│   │   │   ├── fallible_result.rs
│   │   │   ├── flatten.rs
│   │   │   ├── for_each.rs
│   │   │   ├── inspect.rs
│   │   │   ├── iter_consuming.rs
│   │   │   ├── iter_ref.rs
│   │   │   ├── map/
│   │   │   │   ├── collect.rs
│   │   │   │   ├── find.rs
│   │   │   │   ├── mod.rs
│   │   │   │   └── reduce.rs
│   │   │   ├── min_max.rs
│   │   │   ├── mod.rs
│   │   │   ├── range.rs
│   │   │   ├── slice.rs
│   │   │   ├── sum.rs
│   │   │   ├── vectors.rs
│   │   │   └── xap/
│   │   │       ├── collect.rs
│   │   │       ├── find.rs
│   │   │       ├── mod.rs
│   │   │       └── reduce.rs
│   │   └── xap.rs
│   ├── default_fns.rs
│   ├── enumerate/
│   │   └── mod.rs
│   ├── env.rs
│   ├── executor/
│   │   ├── computation_kind.rs
│   │   ├── executor_with_diagnostics/
│   │   │   ├── mod.rs
│   │   │   ├── parallel_executor.rs
│   │   │   ├── shared_state.rs
│   │   │   └── thread_executor.rs
│   │   ├── fixed_chunk_executor/
│   │   │   ├── chunk_size.rs
│   │   │   ├── mod.rs
│   │   │   ├── parallel_executor.rs
│   │   │   └── thread_executor.rs
│   │   ├── mod.rs
│   │   ├── parallel_compute/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── next_any.rs
│   │   │   └── reduce.rs
│   │   ├── parallel_executor.rs
│   │   ├── thread_compute/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── next_any.rs
│   │   │   └── reduce.rs
│   │   └── thread_executor.rs
│   ├── experiment/
│   │   ├── algorithms/
│   │   │   ├── merge_sorted_slices/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── par.rs
│   │   │   │   ├── seq.rs
│   │   │   │   └── tests/
│   │   │   │       ├── inputs.rs
│   │   │   │       ├── mod.rs
│   │   │   │       ├── par.rs
│   │   │   │       └── seq.rs
│   │   │   └── mod.rs
│   │   ├── data_structures/
│   │   │   ├── mod.rs
│   │   │   ├── slice.rs
│   │   │   ├── slice_dst.rs
│   │   │   ├── slice_iter_ptr.rs
│   │   │   ├── slice_iter_ptr_dst.rs
│   │   │   ├── slice_iter_ptr_src.rs
│   │   │   ├── slice_src.rs
│   │   │   └── tests/
│   │   │       ├── mod.rs
│   │   │       └── slice.rs
│   │   └── mod.rs
│   ├── generic_iterator/
│   │   ├── collect.rs
│   │   ├── early_exit.rs
│   │   ├── iter.rs
│   │   ├── mod.rs
│   │   ├── reduce.rs
│   │   └── transformations.rs
│   ├── generic_values/
│   │   ├── fallible_iterators/
│   │   │   ├── mod.rs
│   │   │   └── result_of_iter.rs
│   │   ├── mod.rs
│   │   ├── option.rs
│   │   ├── option_result.rs
│   │   ├── result.rs
│   │   ├── runner_results/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── collect_sequential.rs
│   │   │   ├── fallibility.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── reduce.rs
│   │   │   └── stop.rs
│   │   ├── transformable_values.rs
│   │   ├── values.rs
│   │   ├── vector.rs
│   │   ├── vector_result.rs
│   │   ├── whilst_atom.rs
│   │   ├── whilst_atom_result.rs
│   │   ├── whilst_iterators/
│   │   │   ├── mod.rs
│   │   │   ├── whilst_atom_flat_map.rs
│   │   │   └── whilst_option_flat_map.rs
│   │   ├── whilst_option.rs
│   │   ├── whilst_option_result.rs
│   │   ├── whilst_vector.rs
│   │   └── whilst_vector_result.rs
│   ├── heap_sort.rs
│   ├── into_par_iter.rs
│   ├── iter/
│   │   ├── mod.rs
│   │   ├── recursive/
│   │   │   ├── into_par_rec_iter.rs
│   │   │   ├── mod.rs
│   │   │   └── rec_par_iter.rs
│   │   └── special_iterators.rs
│   ├── iter_into_par_iter.rs
│   ├── lib.rs
│   ├── par_iter.rs
│   ├── par_iter_option.rs
│   ├── par_iter_result.rs
│   ├── par_thread_pool.rs
│   ├── parallel_drainable.rs
│   ├── parallelizable.rs
│   ├── parallelizable_collection.rs
│   ├── parallelizable_collection_mut.rs
│   ├── parameters/
│   │   ├── chunk_size.rs
│   │   ├── iteration_order.rs
│   │   ├── mod.rs
│   │   ├── num_threads.rs
│   │   └── params.rs
│   ├── runner/
│   │   ├── computation_kind.rs
│   │   ├── implementations/
│   │   │   ├── mod.rs
│   │   │   ├── pond.rs
│   │   │   ├── poolite.rs
│   │   │   ├── rayon_core.rs
│   │   │   ├── runner_with_pool.rs
│   │   │   ├── scoped_pool.rs
│   │   │   ├── scoped_threadpool.rs
│   │   │   ├── sequential.rs
│   │   │   ├── std_runner.rs
│   │   │   ├── tests/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── pond.rs
│   │   │   │   ├── poolite.rs
│   │   │   │   ├── rayon_core.rs
│   │   │   │   ├── scoped_pool.rs
│   │   │   │   ├── scoped_threadpool.rs
│   │   │   │   ├── sequential.rs
│   │   │   │   ├── std.rs
│   │   │   │   ├── utils.rs
│   │   │   │   └── yastl.rs
│   │   │   └── yastl.rs
│   │   ├── mod.rs
│   │   ├── num_spawned.rs
│   │   └── parallel_runner.rs
│   ├── special_type_sets/
│   │   ├── mod.rs
│   │   └── sum.rs
│   ├── test_utils.rs
│   ├── using/
│   │   ├── collect_into/
│   │   │   ├── collect.rs
│   │   │   ├── fixed_vec.rs
│   │   │   ├── mod.rs
│   │   │   ├── split_vec.rs
│   │   │   ├── u_par_collect_into.rs
│   │   │   └── vec.rs
│   │   ├── computational_variants/
│   │   │   ├── mod.rs
│   │   │   ├── tests/
│   │   │   │   ├── copied.rs
│   │   │   │   ├── count.rs
│   │   │   │   ├── fallible_option.rs
│   │   │   │   ├── fallible_result.rs
│   │   │   │   ├── flatten.rs
│   │   │   │   ├── for_each.rs
│   │   │   │   ├── inspect.rs
│   │   │   │   ├── iter_consuming.rs
│   │   │   │   ├── iter_ref.rs
│   │   │   │   ├── map/
│   │   │   │   │   ├── collect.rs
│   │   │   │   │   ├── find.rs
│   │   │   │   │   ├── mod.rs
│   │   │   │   │   └── reduce.rs
│   │   │   │   ├── min_max.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── range.rs
│   │   │   │   ├── slice.rs
│   │   │   │   ├── sum.rs
│   │   │   │   ├── utils.rs
│   │   │   │   ├── vectors.rs
│   │   │   │   └── xap/
│   │   │   │       ├── collect.rs
│   │   │   │       ├── find.rs
│   │   │   │       ├── mod.rs
│   │   │   │       └── reduce.rs
│   │   │   ├── u_fallible_option.rs
│   │   │   ├── u_fallible_result/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── u_map_result.rs
│   │   │   │   ├── u_par_result.rs
│   │   │   │   └── u_xap_result.rs
│   │   │   ├── u_map.rs
│   │   │   ├── u_par.rs
│   │   │   └── u_xap.rs
│   │   ├── executor/
│   │   │   ├── mod.rs
│   │   │   ├── parallel_compute/
│   │   │   │   ├── collect_arbitrary.rs
│   │   │   │   ├── collect_ordered.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── next.rs
│   │   │   │   ├── next_any.rs
│   │   │   │   └── reduce.rs
│   │   │   └── thread_compute/
│   │   │       ├── collect_arbitrary.rs
│   │   │       ├── collect_ordered.rs
│   │   │       ├── mod.rs
│   │   │       ├── next.rs
│   │   │       ├── next_any.rs
│   │   │       └── reduce.rs
│   │   ├── mod.rs
│   │   ├── u_par_iter.rs
│   │   ├── u_par_iter_option.rs
│   │   ├── u_par_iter_result.rs
│   │   └── using_variants.rs
│   └── value_variants/
│       ├── whilst_iterators/
│       │   ├── whilst_atom_flat_map.rs
│       │   └── whilst_option_flat_map.rs
│       └── whilst_vector.rs
└── tests/
    ├── chain.rs
    ├── into_par.rs
    ├── iter_into_par.rs
    ├── map_while_ok_collect/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   └── mod.rs
    ├── map_while_ok_collect_arbitrary/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   ├── mod.rs
    │   └── utils.rs
    ├── map_while_ok_reduce/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   └── mod.rs
    ├── mut_iter.rs
    ├── parallel_drainable.rs
    ├── parallelizable.rs
    ├── parallelizable_collection.rs
    ├── test_groups.rs
    ├── trait_bounds.rs
    ├── using/
    │   ├── mod.rs
    │   └── rng.rs
    └── whilst/
        ├── collect.rs
        ├── collect_arbitrary.rs
        ├── find.rs
        ├── mod.rs
        └── reduce.rs

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: [orxfun]


================================================
FILE: .github/workflows/ci.yml
================================================
# Updated workflow (based on .github/workflows/ci.yml at ref d04ad7abce0c67776a7189001f706535e3e5c402)
name: Rust

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        toolchain: ["stable"]
        features: ["", "--all-features", "--no-default-features"]

    steps:
    - uses: actions/checkout@v4

    - name: Cache cargo registry & target
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-stable-${{ matrix.features || 'default' }}

    - name: Install toolchain
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: ${{ matrix.toolchain }}

    - name: Install 32bit target (for builds if needed)
      run: rustup target add i686-unknown-linux-musl

    - name: Install wasm target
      run: rustup target add wasm32-unknown-unknown

    - name: Install miri
      run: rustup component add --toolchain nightly-x86_64-unknown-linux-gnu miri

    - name: Install no-std-check
      run: cargo install cargo-no-std-check

    - name: Build
      run: cargo build --verbose ${{ matrix.features }}

    - name: Build-wasm
      run: cargo build --verbose --target wasm32-unknown-unknown ${{ matrix.features }}

    - name: Test
      run: cargo test --verbose ${{ matrix.features }}

    - name: Check-wasm
      run: cargo check --verbose --target wasm32-unknown-unknown ${{ matrix.features }}

    - name: Clippy
      run: cargo clippy ${{ matrix.features }} -- -D warnings --verbose

    - name: Miri
      run: cargo +nightly miri test --lib --bins --tests --verbose ${{ matrix.features }}


  test-32:
    name: Test (i686)
    runs-on: ubuntu-latest
    needs: build
    env:
      CARGO_TERM_COLOR: always

    steps:
      - uses: actions/checkout@v4

      - name: Cache cargo registry & target
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-stable-i686

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

      - name: Set up QEMU for multi-arch Docker
        uses: docker/setup-qemu-action@v2

      - name: Install Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Install cross
        run: cargo install --locked cross || true

      - name: Run tests for i686 target via cross
        run: |
          # Run unit tests under QEMU inside Docker so i686 test binaries are executed reliably.
          # Uses the glibc i686 target by default. Change to i686-unknown-linux-musl if you require musl.
          cross test --target i686-unknown-linux-gnu --verbose


================================================
FILE: .gitignore
================================================
# Generated by Cargo
# will have compiled files and executables
debug/
target/
.vscode/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

benches/results/*.txt


================================================
FILE: .scripts/run_benchmark.sh
================================================
original_bench=find_iter_into_par
bench=$1

sed -i "s/$original_bench/$bench/g" Cargo.toml

rm -f benches/results/$bench.txt

cargo bench --all-features >> benches/results/$bench.txt

sed -i "s/$bench/$original_bench/g" Cargo.toml


================================================
FILE: .scripts/run_benchmarks.sh
================================================
allBenches=(
    chain_collect_map
    chain3_collect_map
    chain4_collect_map
    collect_filter
    collect_filtermap
    collect_flatmap
    collect_iter_into_par
    collect_long_chain
    collect_map_filter_hash_set
    collect_map_filter
    collect_map
    count_filtermap
    count_flatmap
    count_map_filter
    count_map
    drain_vec_collect_map_filter
    find_any
    find_flatmap
    find_iter_into_par
    find_map_filter
    find
    mut_for_each_iter
    mut_for_each_slice
    reduce_iter_into_par
    reduce_long_chain
    reduce_map_filter
    reduce_map
    reduce
    result_collect_map
    result_reduce_map
    sum_filtermap
    sum_flatmap
    sum_map_filter
    sum
    vec_deque_collect_map_filter
    vec_deque_collect_map_filter_owned
)

counter = 0

for t in ${allBenches[@]}; do
    counter=$((counter+1))
    echo -e "\n\n"
    echo ------------- $counter : $t ----------------------------------
    ./.scripts/run_benchmark.sh $t
done


================================================
FILE: Cargo.toml
================================================
[package]
name = "orx-parallel"
version = "3.4.0"
edition = "2024"
authors = ["orxfun <orx.ugur.arikan@gmail.com>"]
readme = "README.md"
description = "High performance, configurable and expressive parallel computation library."
license = "MIT OR Apache-2.0"
repository = "https://github.com/orxfun/orx-parallel/"
keywords = ["parallel", "concurrency", "performance", "thread", "iterator"]
categories = ["concurrency", "algorithms"]

[dependencies]
orx-pinned-vec = { version = "3.21.0", default-features = false }
orx-fixed-vec = { version = "3.22.0", default-features = false }
orx-split-vec = { version = "3.22.0", default-features = false }
orx-concurrent-iter = { version = "3.3.0", default-features = false }
orx-concurrent-bag = { version = "3.4.0", default-features = false }
orx-concurrent-ordered-bag = { version = "3.4.0", default-features = false }
orx-pinned-concurrent-col = { version = "2.18.0", default-features = false }
orx-iterable = { version = "1.3.0", default-features = false }
orx-priority-queue = { version = "1.7.0", default-features = false }
orx-pseudo-default = { version = "2.1.0", default-features = false }
orx-concurrent-recursive-iter = { version = "2.0.0", default-features = false }

# optional: generic iterator
rayon = { version = "1.11.0", optional = true, default-features = false }

# optional: thread pool
pond = { version = "0.3.1", optional = true, default-features = false }
poolite = { version = "0.7.1", optional = true, default-features = false }
rayon-core = { version = "1.13.0", optional = true, default-features = false }
scoped-pool = { version = "1.0.0", optional = true, default-features = false }
scoped_threadpool = { version = "0.1.9", optional = true, default-features = false }
yastl = { version = "0.1.2", optional = true, default-features = false }

[dev-dependencies]
chrono = "0.4.42"
clap = { version = "4.5.50", features = ["derive"] }
criterion = { version = "0.8", features = ["html_reports"] }
orx-concurrent-option = { version = "1.5.0", default-features = false }
orx-concurrent-vec = "3.10.0"
rand = "0.9.2"
rand_chacha = "0.9"
rayon = "1.11.0"
test-case = "3.3.1"
orx-criterion = { git = "https://github.com/orxfun/orx-criterion" }

[[bench]]
name = "find_iter_into_par"
harness = false

[package.metadata.docs.rs]
all-features = true

[features]
default = ["std"]
std = []
generic_iterator = ["rayon"]
experiment = []


================================================
FILE: LICENSE-APACHE
================================================
                              Apache License
                        Version 2.0, January 2004
                     http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS


================================================
FILE: LICENSE-MIT
================================================
MIT License

Copyright (c) 2024 Ugur Arikan

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# orx-parallel

[![orx-parallel crate](https://img.shields.io/crates/v/orx-parallel.svg)](https://crates.io/crates/orx-parallel)
[![orx-parallel crate](https://img.shields.io/crates/d/orx-parallel.svg)](https://crates.io/crates/orx-parallel)
[![orx-parallel documentation](https://docs.rs/orx-parallel/badge.svg)](https://docs.rs/orx-parallel)

[High performance](#performance-and-benchmarks), [configurable](#configurable) and [expressive](#parallel-computation-by-iterators) parallel computation library.

* [Parallel Computation by Iterators](#parallel-computation-by-iterators)
* [Parallelizable Collections](#parallelizable-collections)
* [Parallelization over Nonlinear Data Structures](#parallelization-over-nonlinear-data-structures)
* [Performance and Benchmarks](#performance-and-benchmarks)
* [Fallible Parallel Iterators](#fallible-parallel-iterators)
* [Using Mutable Variables](#using-mutable-variables)
* [Configurations](#configurations)
* [Runner: Pools and Executors](#runner-pools-and-executors)
* [Contributing](#contributing)

## Parallel Computation by Iterators

Parallel computation is defined using the parallel iterator trait [`ParIter`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html).

The goal is to convert an expressive sequential program into an efficient parallel program only by replacing `iter` with `par`; and `into_iter` with `into_par`.

The following is a naive [traveling salesperson](https://en.wikipedia.org/wiki/Travelling_salesman_problem) algorithm which randomly generates sequences and picks the one with the minimum duration as the best tour. The example demonstrates chaining of very common and useful `map`, `filter` and `reduce` (`min_by_key`) operations. Notice that the only difference between the sequential and parallel programs is the `par()` call.

```rust
use orx_parallel::*;
use rand::prelude::*;

struct Tour(Vec<usize>);

impl Tour {
    fn random(n: usize) -> Self {
        let mut cities: Vec<_> = (0..n).collect();
        cities.shuffle(&mut rand::rng());
        Self(cities)
    }

    fn not_in_standard_order(&self) -> bool {
        self.0.iter().enumerate().any(|(i, c)| i != *c)
    }

    fn duration(&self) -> usize {
        let mut total = 0;
        let links = self.0.iter().zip(self.0.iter().skip(1));
        for (a, b) in links {
            total += (*a as i64 - *b as i64).abs() as usize;
        }
        total
    }
}

let num_tours = 1_000_000;
let num_cities = 10;

// sequential
let best_tour = (0..num_tours)
    .map(|_| Tour::random(num_cities))
    .filter(|t| t.not_in_standard_order())
    .min_by_key(|t| t.duration())
    .unwrap();

// parallel
let best_tour = (0..num_tours)
    .par() // parallelized !!
    .map(|_| Tour::random(num_cities))
    .filter(|t| t.not_in_standard_order())
    .min_by_key(|t| t.duration())
    .unwrap();
```

## Parallelizable Collections

Inputs that can be used in parallel computations can be categorized in three groups:

* i. directly parallelizable collections
* ii. parallelization of any iterator
* iii. parallelization of any collection

### i. Directly Parallelizable Collections

These are collections which are parallelized by utilizing their specific structure to achieve high performance.

This crate provides direct implementations of std collections; the table below lists the most recent table of direct implementations.


| Type | Over References<br>`&T` | Over Mut References <br>`&mut T>` | Over Owned Values<br>` T` |
|:--|:-:|:-:|:-:|
| `v: Vec<T>` | `v.par()` | `v.par_mut()` | `v.into_par()` |
| `v: VecDeque<T>` | `v.par()` | | `v.into_par()` |
| `s: &[T]` | `s.par()`<br>`s.into_par()` | | |
| `s: &mut [T]` | | `s.into_par()` | |
| `r: Range<usize>`| | | `r.par()`<br>`r.into_par()` |

Implementations of custom collections belong to their respective crates as they most likely require access to internals. Currently, the following collections are known to allow parallel computation using this crate:

│ [SplitVec](https://crates.io/crates/orx-split-vec) │ [FixedVec](https://crates.io/crates/orx-fixed-vec) │ [LinkedList](https://crates.io/crates/orx-linked-list) │ [Tree](https://crates.io/crates/orx-tree) │ [ImpVec](https://crates.io/crates/orx-imp-vec) │

Since these implementations are particularly optimized for the collection type, it is preferable to start defining parallel computation from the collection whenever available. In other words, for a direclty parallelizable collection `col`,

* `col.par().map(_).filter(_).reduce(_)` is a better approach than
* `col.iter().iter_into_par().map(_).filter(_).reduce(_)`, which will be explained in the next subsection.

> **extensibility**: Note that any input collection or generator that implements [`IntoConcurrentIter`](https://docs.rs/orx-concurrent-iter/latest/orx_concurrent_iter/trait.IntoConcurrentIter.html) automatically implements [`IntoParIter`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.IntoParIter.html). Therefore, a new collection can be parallelized provided that its concurrent iterator is implemented.

In addition, there exist the following special parallel iterators that can be directly created from the collection.

| Type | Method | Definition |
|---|---|---|
| `v: Vec<T>` | [`v.par_drain(range)`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParallelDrainableOverSlice.html) | Parallel counterpart of `v.drain(range)` |

### ii. Parallelization of Any Iterator

Any arbitrary sequential [Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) implements [`IterIntoParIter`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.IterIntoParIter.html) trait and can be converted into a parallel iterator using the `iter_into_par` method.

As demonstrated below, item type of the Iterator can as well be a mutable reference.

```rust
use orx_parallel::*;
use std::collections::HashMap;

let mut map: HashMap<_, _> = (0..1024).map(|x| (x.to_string(), x)).collect();

let par = map.values_mut().iter_into_par(); // mutable parallel iterator from Iterator
par.filter(|x| **x != 42).for_each(|x| *x *= 0);

assert_eq!(map.values().iter_into_par().sum(), 42); // parallel iterator from Iterator
```

This is powerful since it allows to parallelize all iterables, including pretty much every collection and more.

On the other hand, due to being a generic implementation without collection specific optimizations, parallelized computation might underperform its sequential counterpart if the work to be done on each input element is insignificant. For instance, `i` being an arbitrary iterator of numbers, `i.sum()` will most likely be faster than `i.iter_into_par().sum()`.

This being said, `ParIter` takes advantage of certain optimizations, such as buffering and chunk size optimization, in order to improve performance. Therefore, whenever the computation on the iterator elements is more involved than just returning them or adding numbers, we can benefit from parallelization. The respective section of [benchmarks](#parallelization-of-arbitrary-iterators) present significant improvements achieved consistently.

### iii. Parallelization of Any Collection

Lastly, consider a collection which does not provide a direct concurrent iterator implementation. This might be our custom collection, say `MyCollection`; or an external collection without a concurrent iterator implementation, such as the `HashSet<T>`.

There are two methods to parallelize computations over such collections:
* (ii) parallelize using the collection's iterator, or
* (i) collect the elements in a vector and then parallelize work over the vector.

The following table demonstrates these methods for the `HashSet`; however, they are applicable to any collection with `iter` and `into_iter` methods.

| Type | Method | Over References<br>`&T` | Over Owned Values<br>`T` |
|:--|:-:|---|---|
| `h: HashSet<T>` | ii | `h.iter()`<br>&nbsp;&nbsp;`.iter_into_par()` | `h.into_iter()`<br>&nbsp;&nbsp;`.iter_into_par()` |
|                 | i  | `h.iter()`<br>&nbsp;&nbsp;`.collect::<Vec<_>>()`<br>&nbsp;&nbsp;`.par()` | `h.into_iter()`<br>&nbsp;&nbsp;`.collect::<Vec<_>>()`<br>&nbsp;&nbsp;`.into_par()` |

Note that each approach can be more efficient in different scenarios. For large elements, (ii) might be preferred to avoid allocation of the vector. For insignificant tasks to be performed on each element, (i) might be preferred to take full benefit of vector-specific optimizations.

## Parallelization over Nonlinear Data Structures

[IntoParIterRec](https://docs.rs/orx-parallel/latest/orx_parallel/trait.IntoParIterRec.html) trait can be used to create a **parallel recursive iterator** over an initial set of elements which is useful when working with non-linear data structures such as **trees** and **graphs**.

Consider, for instance, a tree which is defined by the following node struct:

```rust ignore
pub struct Node<T> {
    pub data: T,
    pub children: Vec<Node<T>>,
}
```

Assume that we want to map all the data with `map: impl Fn(T) -> u64` and compute the sum of mapped values of all nodes descending from a `root: &Node`.

We can express this computation and execute in parallel with the following:

```rust ignore
fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
    queue.extend(&node.children);
}

[root].into_par_rec(extend).map(map).sum()
```

Instead of `into_par`, we use `into_par_rec` and provide `extend` function as its argument. This function defines the recursive extension of the parallel iterator such that every time we process a `node` we first add its children to the `queue`. [`Queue`](https://docs.rs/orx-concurrent-recursive-iter/latest/orx_concurrent_recursive_iter/struct.Queue.html) is the queue of elements to be processed and it exposes two growth methods to define the recursive extension: `push` and `extend`.

Although we create the parallel iterator differently, we get a `ParIter`. Therefore, we have access to all features of a regular parallel iterator.

For instance, assume we want to filter nodes first. Further, instead of summing up the mapped values, we need to collect them in a vector. We can express this computation just as we would do on a linear data structure:

```rust ignore
[root].into_par_rec(extend).filter(filter).map(map).collect()
```

For more details, you may see the [parallelization_on_tree](https://github.com/orxfun/orx-parallel/blob/main/examples/parallelization_on_tree) example.

## Performance and Benchmarks

*Please also see [impact of ChunkSize on performance](#impact-of-chunksize-on-performance) section.*

You may find some sample parallel programs in [examples](https://github.com/orxfun/orx-parallel/blob/main/examples) directory. These examples allow to express parallel computations as iterator method compositions and run quick experiments with different approaches. Examples use `GenericIterator`. As the name suggests, it is a generalization of sequential iterator, rayon's parallel iterator and orx-parallel's parallel iterator, and hence, allows for convenient experiments. You may play with the code, update the tested computations and run these examples by including **generic_iterator** feature, such as:

`cargo run --release --features generic_iterator --example benchmark_collect -- --len 123456 --num-repetitions 10`

Actual benchmark files are located in [benches](https://github.com/orxfun/orx-parallel/blob/main/benches) directory. Tables below report average execution times in microseconds. The numbers in parentheses represent the ratio of execution time to that of sequential computation which is used as the baseline (1.00). Parallelized executions of all benchmarks are carried out with default settings. 

Computations are separated into three categories with respect to how the iterator is consumed: collect, reduce and early-exit. Further, two additional categories are created to test parallelization of arbitrary iterators ([ii](#ii-parallelization-of-any-iterator)) and flexibility in composition of computations.

### Collect

In this group of benchmarks, outputs of parallel computations are collected into vectors. Details of the iterator chains and tested functions can be found in the respective benchmark files (you may use the link in the **file** column).

> **(s)** Outputs can also be collected into a [`SplitVec`](https://crates.io/crates/orx-split-vec), which can provide further improvements by avoiding memory copies. Note that a split vector provides constant time random access; and despite the fact that it is split to fragments, it asymptotically inherits advantages of contiguous vectors.

|file|computation|sequential|rayon|orx-parallel|orx-parallel (s)|
|---|---|---:|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_filter.rs)|`.filter(_).collect()`|2.74 (1.00)|12.14 (4.43)|**1.80 (0.66)**|1.87 (0.68)|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_filtermap.rs)|`.filter_map(_).collect()`|6.96 (1.00)|13.28 (1.91)|3.51 (0.50)|**3.35 (0.48)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_flatmap.rs)|`.flat_map(_).collect()`|77.93 (1.00)|239.83 (3.08)|31.73 (0.41)|**23.79 (0.31)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_map_filter.rs)|`.map(_).filter(_).collect()`|19.24 (1.00)|9.99 (0.52)|6.21 (0.32)|**5.98 (0.31)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_map.rs)|`.map(_).collect()`|18.08 (1.00)|7.98 (0.44)|**5.28 (0.29)**|6.09 (0.34)|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/drain_vec_collect_map_filter.rs)|`.map(_).filter(_).collect()` [☆][draining_iterator]|19.41 (1.00)|7.54 (0.39)|5.90 (0.30)|**5.77 (0.30)**|

[draining_iterator]: ## "parallel draining iterator"


### Reduce

In this group, instead of collecting outputs, the results are reduced to a single value. Some common reductions are `sum`, `count`, `min`, etc.

|file|computation|sequential|rayon|orx-parallel|
|---|---|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/reduce_map_filter.rs)|`.map(_).filter(_).reduce(_)`|14.15 (1.00)|7.55 (0.53)|**3.86 (0.27)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/reduce_map.rs)|`.map(_).reduce(_)`|13.81 (1.00)|6.25 (0.45)|**4.15 (0.30)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/reduce.rs)|`.reduce(_)`|0.97 (1.00)|10.58 (10.91)|**0.90 (0.93)**|


### Find

Here, computations that allow for *early exit* or *short-circuit* are investigated. As an example, experiments on `find` method are presented; methods such as `find_any`, `any` or `all` lead to similar results.

|file|computation|sequential|rayon|orx-parallel|
|---|---|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/)|`.flat_map(_).find(_)`|160.24 (1.00)|127.37 (0.79)|**27.66 (0.17)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/)|`.map(_).filter(_).find(_)`|43.01 (1.00)|11.14 (0.26)|**8.61 (0.20)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/)|`.find(_)`|2.94 (1.00)|12.85 (4.37)|**1.54 (0.52)**|


### Parallelization of Arbitrary Iterators

As discussed in [ii](#ii-parallelization-of-any-iterator), parallelization of regular iterators is a powerful feature. The benchmarks in this category demonstrate that improvements can be achieved provided that the computation on elements is not insignificant.

|file|computation|sequential|rayon|orx-parallel|
|---|---|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_long_chain.rs)|`…long_chain.collect()`|19.72 (1.00)|32.54 (1.65)|**6.12 (0.31)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/reduce_iter_into_par.rs)|`.map(_).filter(_).reduce(_)`|15.17 (1.00)|118.28 (7.80)|**4.98 (0.33)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/)|`.map(_).filter(_).find(_)`|42.58 (1.00)|63.60 (1.49)|**7.98 (0.19)**|

### Parallel Mutable Iterators

In this group, we investigate the performance of parallel computation which mutates the input elements. In the benchmarks, we filter elements and update the ones which satisfy the given criterion within the `for_each` call.

|file|computation|sequential|rayon|orx-parallel|
|---|---|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/mut_for_each_slice.rs)|`slice.par_mut().filter(_).for_each(_)`|62.61 (1.00)|14.08 (0.22)|**8.45 (0.13)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/mut_for_each_iter.rs)|`iter.iter_into_par().filter(_).for_each(_)`|77.63 (1.00)|78.69 (1.01)|**10.03 (0.13)**|


### Composition

In the final category of benchmarks, impact of long chains of transformations on computation time is tested. You may see such example long chains in the benchmark computations below, where `long_chain` is a shorthand for `.map(map1).filter(filter1).map(map2).filter(filter2).map(map3).map(map4).filter(filter4)`. Notice that the caller can actually shorten the chains by composing some of them. An obvious one is the `.map(map3).map(map4)` call which could have been one call like `map(map3-then-map4)`. However, this is not always possible as the computation might be conditionally built up in stages. Further, breaking transformations into smaller pieces help in achieving more descriptive computation definitions.

The results suggest that the functions are efficiently composed by the parallel iterator.

|file|computation|sequential|rayon|orx-parallel|
|---|---|---:|---:|---:|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_long_chain.rs)|`…long_chain.collect()`|14.27 (1.00)|6.33 (0.44)|**3.80 (0.27)**|
|[⇨](https://github.com/orxfun/orx-parallel/blob/main/benches/reduce_long_chain.rs)|`…long_chain.reduce(_)`|15.08 (1.00)|6.10 (0.40)|**4.03 (0.27)**|

## Fallible Parallel Iterators

We enjoy rust's [`?`](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator) operator when working with fallible computations. It allows us to focus on and code only the success path. Failure at any step of the computation leads to a short-circuit and immediately returns from the function.

```rust
fn try_to_parse() -> Result<i32, std::num::ParseIntError> {
    let x: i32 = "123".parse()?; // x = 123
    let y: i32 = "24a".parse()?; // returns an Err() immediately
    Ok(x + y)                    // Doesn't run.
}
```

However, we do not have this convenience while working with iterators.

`collect` is the only exception. Normally, it allows us to pick the container to collect the items into.

```rust
let into_vec: Vec<usize> = (0..10).collect();
let into_set: std::collections::HashSet<usize> = (0..10).collect();
```

But it also does something exceptional when the item type is a result:
* The first computation below is similar to above, it simply collects each element to the container which is defined as a vector.
* The second computation; however, is fundamentally different. It collects elements iff all elements are of the Ok variant. Further, it short-circuits the computation as soon as an Err is observed. This is exactly how the `?` operator behaves.

```rust
let into_vec_of_results: Vec<Result<usize, char>> = (0..10).map(|x| Ok(x)).collect();
let into_result_of_vec: Result<Vec<usize>, char> = (0..10).map(|x| Ok(x)).collect();
```

Although convenient, change in the behavior of the collect computation might be considered *unexpected*, at least for me.

Further, we do have not short-circuiting methods for computations other than collect. For instance, it is not as convenient to compute the sum of numbers of an iterator provided that all elements are of the Ok variant, and receive the error otherwise.

In general, the requirement to early exit in fallible computation is common and important both for performance and convenience reasons.

For parallel computation, this crate proposes to explicitly transform an iterator with fallible elements into a fallible parallel iterator.

```rust
use orx_parallel::*;
use std::num::ParseIntError;

let collect: Result<Vec<i32>, ParseIntError> = vec!["7", "2", "34"]
    .into_par()
    .map(|x| x.parse::<i32>())
    .into_fallible_result() // <-- explicit transformation to fallible iterator
    .collect();
```

Currently, there exist two fallible parallel iterators [`ParIterResult`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIterResult.html) and [`ParIterOption`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIterOption.html). The transformation is as follows:

| Regular Iterator | Transformation  Method| Fallible Iterator |
| --- | --- | --- |
| `ParIter<Item=Result<T, E>>` | `into_fallible_result()` | `ParIterResult<Item=T, Error=E>` |
| `ParIter<Item=Option<T>>` | `into_fallible_option()` | `ParIterOption<Item=T>` |

After converting into a fallible iterator, each chaining transformation is based on the success item type. Similar to `?` operator, this allows us to focus on the success path while any error case will be handled by early returning from the iterator with the error.

```rust
use orx_parallel::*;
use std::num::ParseIntError;

let sum: Result<i32, ParseIntError> = vec!["7", "2", "34"]
    .into_par()
    .map(|x| x.parse::<i32>()) // Item = Result<i32, ParseIntError>
    .into_fallible_result() // we are only working with success type after this point
    .map(|x| x + 1)
    .filter(|x| x % 2 == 0)
    .flat_map(|x| [x, x + 1, x + 2])
    .sum(); // returns Result, rather than i32
assert_eq!(sum, Ok(27));

let sum: Result<i32, ParseIntError> = vec!["7", "!!!", "34"]
    .into_par()
    .map(|x| x.parse::<i32>())
    .into_fallible_result()
    .map(|x| x + 1)
    .filter(|x| x % 2 == 0)
    .flat_map(|x| [x, x + 1, x + 2])
    .sum();
assert!(sum.is_err());
```

As demonstrated above, not only `collect` but all computation methods return a `Result`.

To summarize:
* We can use all iterator methods with fallible iterators as well.
* The transformations are based on the success type. All computations return a `Result`:
  * if all computations succeed, it is `Ok` of the value that an infallible iterator would return;
  * it is the first discovered `Err` if any of the computations fails.
* Finally, all computations immediately return in case of an error.

Optional fallible iterator behaves exactly the same, except that `None` is treated as the failure case.

## Using Mutable Variables

Iterator methods allow us to define expressive computations using closures. These closures are often `FnMut` for sequential iterators allowing to mutably capture variables from the scope. It is clear that this is not possible for parallel iterators as it would lead to race condition when multiple threads simultaneously try to access the captured mutable variable. Therefore, parallel counterpart of the iterator methods often accept closures implementing `Fn`.

However, it is necessary to have mutable variables for certain programs. A very common example is computations requiring random number generators which are stateful and can create random numbers only with a mutable reference.

**using** transformation aims to provide a general and safe solution to this problem as follows:
* One mutable variable per thread; hence, no race conditions.
* The mutable variable is explicitly and mutably available to all iterator methods.

The following two examples demonstrate the idea and usage:

* [`using`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html#tymethod.using) takes a closure with thread index as the argument, describing how the mutable variable should be created for each thread.
* [`using_clone`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html#tymethod.using_clone), on the other hand, takes the value to be used as the mutable variable and shares a clone of it with each thread (just a shorthand for `using(|_| sender.clone())`).

In either case, there will exactly be `n` mutable variables created provided that the parallel computation uses `n` threads.

```rust ignore
input
    .into_par()
    .using(|t_idx| ChaCha20Rng::seed_from_u64(42 * t_idx as u64)) // <-- explicit using
    .map(|_, i| fibonacci((i % 50) + 1) % 10)       // rng: &mut ChaCha20Rng
    .filter(|rng, _: &u64| rng.random_bool(0.4))    // is accessible for
    .map(|rng, i: u64| rng.random_range(0..i))      // all iterator methods
    .sum()

let (sender, receiver) = channel();
```

```rust ignore
let (sender, receiver) = channel();
(0..5)
    .into_par()
    .using_clone(sender)
    .for_each(|s, x| s.send(x).unwrap());

let mut res: Vec<_> = receiver.iter().collect();
```

Further details can be found in [using.md](https://github.com/orxfun/orx-parallel/blob/main/docs/using.md).

## Configurations

### Configuration per Computation

Each parallel computation is governed by two main straightforward parameters.

[`NumThreads`](https://docs.rs/orx-parallel/latest/orx_parallel/enum.NumThreads.html) is the degree of parallelization. This is a *capacity parameter* used to limit the resources that can be used by the computation.
* `Auto`: All available threads can be used, but not necessarily.
* `Max(n)`: The computation can spawn at most n threads.
* `Max(1)`: Falls back to sequential execution on the main thread.

[`ChunkSize`](https://docs.rs/orx-parallel/latest/orx_parallel/enum.ChunkSize.html) represents the number of elements a parallel worker will pull and process every time it becomes idle. This is an *optimization parameter* that can be tuned to balance the overhead of parallelization and cost of heterogeneity of tasks.
* `Auto`: Let the parallel executor dynamically decide, achieves high performance in general and can be used unless we have useful computation specific knowledge.
* `Exact(c)`: Chunks will have c elements; gives complete control to the caller. Useful when we have a very good knowledge or want to tune the computation for certain data.
* `Min(c)`: Every chunk will have at least c elements. Parallel executor; however, might decide to pull more if each computation is handled very fast.

See also the last parameter [`IterationOrder`](https://docs.rs/orx-parallel/latest/orx_parallel/enum.IterationOrder.html) with variants `Ordered` (default) and `Arbitrary` which is another useful optimization parameter for specific use cases.

When omitted, `NumThreads::Auto` and `ChunkSize::Auto` will be used. Configuring parallel computation is **straightforward** and **specific to computation** rather than through a global setting.

```rust
use orx_parallel::*;
use std::num::NonZeroUsize;

let n = 1024;

_ = (0..n).par().sum(); // NumThreads::Auto & ChunkSize::Auto

_ = (0..n).par().num_threads(4).sum(); // <= 4 threads
_ = (0..n).par().num_threads(1).sum(); // sequential
_ = (0..n).par().num_threads(0).sum(); // shorthand for NumThreads::Auto

_ = (0..n).par().chunk_size(64).sum(); // chunks of exactly 64 elements
let c = ChunkSize::Min(NonZeroUsize::new(16).unwrap());
_ = (0..n).par().chunk_size(c).sum(); // chunks of at least 16 elements

_ = (0..n).par().num_threads(4).chunk_size(16).sum(); // set both params
```

Note that `NumThreads::Max(1)` executes the computation sequentially.

This gives the consumer, who actually executes the defined computation, complete control to:

* execute in parallel with the given configuration, or
* execute sequentially, or
* execute in parallel with any number of threads that it decides.

This is guaranteed by the fact that both consuming computation calls and configuration methods require ownership (`self`) of the iterator.

### Global Configuration

Additionally, maximum number of threads that can be used by parallel computations can be globally bounded by the environment variable `ORX_PARALLEL_MAX_NUM_THREADS`. Please see the corresponding [example](https://github.com/orxfun/orx-parallel/blob/main/examples/max_num_threads_config.rs) for details.

### Impact of `ChunkSize` on Performance

The impact of the chunk size on performance might be significant.

Our objective is to minimize the sum of two computational costs:
* parallelization overhead => it gets smaller as chunk size gets greater
* cost of heterogeneity => it gets larger as chunk size gets greater

Parallelization overhead can further be divided into two:
* concurrent state update: This often corresponds to one atomic update per chunk. It may be significant if our computation is very small such as `input.par().sum()`. Otherwise, cost of atomic update could be negligible.
* false sharing: This is relevant only if we are writing results. For instance, when we are one-to-one mapping an input and collecting the results such as `input.par().map(|x| x.to_string()).collect()`, or if are writing with mut references such as `input.par().for_each(|x| *x += 1)`. Here, the performance might suffer from false sharing when the `chunk size × size of output item` is not large enough. You may also see [false sharing](https://docs.rs/orx-concurrent-bag/latest/orx_concurrent_bag/#false-sharing) section for `ConcurrentBag`.

In either case, when computation on each item is sufficiently long, parallelization overhead is negligible. Here, we want to make sure that we do not have heterogeneity cost. Therefore, a safe chunk size choice would be one, `par.chunk_size(1)`.

Otherwise, our choice depends on the use case. As a rule of thumb, we want a chunk size that is **just large enough** to mitigate the parallelization overhead but not larger so that we do not suffer from heterogeneity.

The default configuration `par.chunk_size(ChunkSize::Auto)` or `par.chunk_size(0)` uses a heuristic to solve this tradeoff. A difficult case for the current version is when the tasks are significantly heterogeneous (see the [discussion](https://github.com/orxfun/orx-parallel/discussions/26) for future improvements).

As described above, the **best way to deal with heterogeneity** is to have `par.chunk_size(1)`. You may of course test larger chunk sizes to optimize the computation for your data.


## Runner: Pools and Executors

This crate defines parallel computation by combining two basic components.

**Pulling inputs**
* Pulling inputs in parallel is achieved through [`ConcurrentIter`](https://crates.io/crates/orx-concurrent-iter). Concurrent iterator implementations are lock-free, efficient and support pull-by-chunks optimization to reduce the parallelization overhead. A thread can pull any number of inputs from the concurrent iterator every time it becomes idle. This provides the means to dynamically decide on the chunk sizes.
* Furthermore, this allows to reduce the overhead of defining creating tasks. To illustrate, provided that the computation will be handled by `n` threads, a closure holding a reference to the input concurrent iterator is defined to represent the computation. This same closure is passed to `n` threads; i.e., `n` spawn calls are made. Each of these threads keep pulling elements from the input until the computation is completed, without requiring to define another task.

**Writing outputs**
* When we collect results, writing outputs is handled using lock-free containers such as [`ConcurrentBag`](https://crates.io/crates/orx-concurrent-bag) and [`ConcurrentOrderedBag`](https://crates.io/crates/orx-concurrent-ordered-bag) which aim for high performance collection of results.

There are two main decisions to be taken while executing these components:
* how many threads do we use?
* what is the chunk size; i.e., how many input items does a thread pull each time?

A [`ParallelRunner`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParallelRunner) is a combination of a `ParThreadPool` and a `ParallelExecutor` that are responsible for these decisions, respectively.

### ParThreadPool: number of threads

[`ParThreadPool`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParThreadPool) trait generalizes thread pools that can be used for parallel computations. This allows the parallel computation to be generic over thread pools.

When not explicitly set, [`DefaultPool`](https://docs.rs/orx-parallel/latest/orx_parallel/type.DefaultPool) is used:
* When **std** feature is enabled, default pool is the [`StdDefaultPool`](https://docs.rs/orx-parallel/latest/orx_parallel/struct.StdDefaultPool). In other words, all available native threads can be used by the parallel computation. This number can globally bounded by "ORX_PARALLEL_MAX_NUM_THREADS" environment variable when set.
* When working in a **no-std** environment, default pool is the [`SequentialPool`](https://docs.rs/orx-parallel/latest/orx_parallel/struct.SequentialPool). As the name suggests, this pool executes the parallel computation sequentially on the main thread. It can be considered as a placeholder to be overwritten by `with_pool` or `with_runner` methods to achieve parallelism.

*Note that thread pool defines the resource, or upper bound. This upper bound can further be bounded by the [`num_threads`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html#tymethod.num_threads) configuration. Finally, parallel executor might choose not to use all available threads if it decides that the computation is small enough.*

To overwrite the defaults and explicitly set the thread pool to be used for the computation, [`with_pool`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html#tymethod.with_pool) or [`with_runner`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html#tymethod.with_runner) methods are used.

```rust
use orx_parallel::*;

let inputs: Vec<_> = (0..42).collect();

// uses the DefaultPool
// assuming "std" enabled, StdDefaultPool will be used; i.e., native threads
let sum = inputs.par().sum();

// equivalent to:
#[cfg(feature = "std")]
{
    let sum2 = inputs.par().with_pool(StdDefaultPool::default()).sum();
    assert_eq!(sum, sum2);
}

#[cfg(not(miri))]
#[cfg(feature = "scoped_threadpool")]
{
    let mut pool = scoped_threadpool::Pool::new(8);
    // uses the scoped_threadpool::Pool created with 8 threads
    let sum2 = inputs.par().with_pool(&mut pool).sum();
    assert_eq!(sum, sum2);
}

#[cfg(not(miri))]
#[cfg(feature = "rayon-core")]
{
    let pool = rayon_core::ThreadPoolBuilder::new()
        .num_threads(8)
        .build()
        .unwrap();
    // uses the rayon-core::ThreadPool created with 8 threads
    let sum2 = inputs.par().with_pool(&pool).sum();
    assert_eq!(sum, sum2);
}

#[cfg(not(miri))]
#[cfg(feature = "yastl")]
{
    let pool = YastlPool::new(8);
    // uses the yastl::Pool created with 8 threads
    let sum2 = inputs.par().with_pool(&pool).sum();
    assert_eq!(sum, sum2);
}
```

`ParThreadPool` implementations of several thread pools are provided in this crate as optional features (see [features](#features) section). Provided that the pool supports scoped computations, it is trivial to implement this trait in most cases (see [implementations](https://github.com/orxfun/orx-parallel/tree/main/src/runner/implementations) for examples).

In most of the cases, *rayon-core*, *scoped_threadpool* and *scoped_pool* perform better than others, and get close to native threads performance with `StdDefaultPool`.

Since parallel computations are generic over the thread pools, performances can be conveniently compared for specific use cases. Such an example benchmark can be found in [collect_filter_map](https://github.com/orxfun/orx-parallel/blob/main/benches/collect_filter_map.rs) file. To have quick tests, you may also use the example [benchmark_pools](https://github.com/orxfun/orx-parallel/blob/main/examples/benchmark_pools.rs).

### ParallelExecutor: chunk size

Once thread pool provides the computation resources, it is [`ParallelExecutor`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParallelExecutor)'s task to distribute work to available threads. As mentioned above, all threads receive exactly the same closure. This closure continues to pull elements from the input concurrent iterator and operate on the inputs until all elements are processed.

The critical decision that parallel executor makes is the chunk size. Depending on the state of the computation, it can dynamically decide on number of elements to pull from the input iterator. The tradeoff it tries to solve is as follows:

* the larger the chunk size,
  * the smaller the parallelization overhead; but also
  * the larger the risk of imbalance in cases of heterogeneity.

## Features

* **std**: This is a **no-std** crate while *std* is included as a default feature. Please use `--no-default-features` flag for no-std use cases. **std** feature enables `StdDefaultPool` as the default thread provider which uses native threads.
* **rayon-core**: This feature enables using `rayon_core::ThreadPool` for parallel computations.
* **scoped_threadpool**: This feature enables using `scoped_threadpool::Pool`.
* **scoped-pool**: This feature enables using `scoped-pool::Pool`.
* **yastl**: This feature enables using `yastl::Pool`.
* **pond**: This feature enables using `pond::Pool`.
* **poolite**: This feature enables using `poolite::Pool`.

## Contributing

Contributions are welcome! 

Please open an [issue](https://github.com/orxfun/orx-parallel/issues/new) or create a PR,

* if you notice an error,
* have a question or think something could be improved,
* have an input collection or generator that needs to be parallelized,
* want to use a particular thread pool with parallel iterators,
* having trouble representing a particular parallel computation with parallel iterators,
* or anything else:)

Finally, feel free to contact [me](mailto:orx.ugur.arikan@gmail.com) if you are interested in optimization of the parallel runner to further improve performance, *by maybe dynamic optimization of chunk size decisions with respect to online collection and analysis of metrics*.

## License

Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT).


================================================
FILE: benches/chain3_collect_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().chain(inputs).chain(inputs).map(map).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs
        .into_par()
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs
        .into_par()
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("chain3_collect_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/chain4_collect_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs
        .iter()
        .chain(inputs)
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .chain(inputs)
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs
        .into_par()
        .chain(inputs)
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs
        .into_par()
        .chain(inputs)
        .chain(inputs)
        .chain(inputs)
        .map(map)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("chain4_collect_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/chain_collect_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().chain(inputs).map(map).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().chain(inputs).map(map).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs.into_par().chain(inputs).map(map).collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs.into_par().chain(inputs).map(map).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("chain_collect_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &&Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<Output> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .map(|x| to_output(&x))
        .collect()
}

fn seq(inputs: &[Output]) -> Vec<&Output> {
    inputs.iter().filter(filter).collect()
}

fn rayon(inputs: &[Output]) -> Vec<&Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().filter(filter).collect()
}

fn orx_into_vec(inputs: &[Output]) -> Vec<&Output> {
    inputs.into_par().filter(filter).collect()
}

fn orx_into_split_vec(inputs: &[Output]) -> SplitVec<&Output> {
    inputs.into_par().filter(filter).collect()
}

#[allow(dead_code)]
fn orx_into_vec_with<P: ParThreadPool>(inputs: &[Output], pool: P) -> Vec<&Output> {
    inputs.into_par().with_pool(pool).filter(filter).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });

        #[cfg(feature = "rayon-core")]
        group.bench_with_input(
            BenchmarkId::new("orx-vec (rayon-core::ThreadPool)", n),
            n,
            |b, _| {
                let pool = rayon_core::ThreadPoolBuilder::new()
                    .num_threads(32)
                    .build()
                    .unwrap();
                assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
                b.iter(|| orx_into_vec_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "scoped-pool")]
        group.bench_with_input(
            BenchmarkId::new("orx-vec (scoped-pool::Pool)", n),
            n,
            |b, _| {
                let pool = scoped_pool::Pool::new(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
                b.iter(|| orx_into_vec_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "scoped_threadpool")]
        group.bench_with_input(
            BenchmarkId::new("orx-vec (scoped_threadpool::Pool)", n),
            n,
            |b, _| {
                let pool = || scoped_threadpool::Pool::new(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, pool()));
                b.iter(|| orx_into_vec_with(black_box(&input), pool()))
            },
        );

        #[cfg(feature = "yastl")]
        group.bench_with_input(BenchmarkId::new("orx-vec (yastl::Pool)", n), n, |b, _| {
            let pool = YastlPool::new(32);
            assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
            b.iter(|| orx_into_vec_with(black_box(&input), &pool))
        });

        #[cfg(feature = "pond")]
        group.bench_with_input(BenchmarkId::new("orx-vec (pond::Pool)", n), n, |b, _| {
            let pool = || PondPool::new_threads_unbounded(32);
            assert_eq!(&expected, &orx_into_vec_with(&input, pool()));
            b.iter(|| orx_into_vec_with(black_box(&input), pool()))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_filtermap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn filter_map(idx: &usize) -> Option<Output> {
    idx.is_multiple_of(3).then(|| to_output(idx))
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().filter_map(filter_map).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().filter_map(filter_map).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs.into_par().filter_map(filter_map).collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs.into_par().filter_map(filter_map).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_filtermap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_flatmap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn flat_map(idx: &usize) -> Vec<Output> {
    (0..4).map(|i| to_output(&(idx + i))).collect::<Vec<_>>()
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().flat_map(flat_map).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().flat_map(flat_map).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs.into_par().flat_map(flat_map).collect()
}

fn orx_sorted_into_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs.into_par().flat_map(flat_map).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_flatmap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_sorted_into_vec(&input));
            b.iter(|| orx_sorted_into_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_iter_into_par.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::ParallelBridge;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().map(map).filter(filter).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.iter().par_bridge().map(map).filter(filter).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs
        .iter()
        .iter_into_par()
        .map(map)
        .filter(filter)
        .collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs
        .iter()
        .iter_into_par()
        .map(map)
        .filter(filter)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_iter_into_par");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            // TODO: for some reason rayon does not return an ordered collection, create an issue
            // assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_long_chain.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 29;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out1 {
    name: String,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out2 {
    name: String,
    number: u32,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out3 {
    out2: Out2,
    fib: u32,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out4 {
    a: String,
    b: char,
    fib: u32,
}

fn map1(idx: &usize) -> Out1 {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32 % FIB_UPPER_BOUND));
    let name = format!("{}-fib-{}", prefix, fib);
    Out1 { name }
}

fn filter1(output: &Out1) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn map2(input: Out1) -> Out2 {
    let number = (FIB_UPPER_BOUND + input.name.len() as u32).saturating_sub(10);
    let number = fibonacci(&(number & FIB_UPPER_BOUND));
    Out2 {
        name: number.to_string(),
        number,
    }
}

fn filter2(output: &Out2) -> bool {
    output.number.is_multiple_of(2) || output.name.contains('0')
}

fn map3(input: Out2) -> Out3 {
    let fib = fibonacci(&input.number);
    Out3 { out2: input, fib }
}

fn map4(input: Out3) -> Out4 {
    let a = format!("{}!", input.out2.name);
    let b = input.out2.name.chars().next().unwrap();
    let fib = fibonacci(&((input.out2.number * 7) % FIB_UPPER_BOUND));
    Out4 { a, b, fib }
}

fn filter4(output: &Out4) -> bool {
    output.a.len() == 5 || output.b == 'x' || output.fib % 2 == 1
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Out4> {
    inputs
        .iter()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .collect()
}

fn rayon(inputs: &[usize]) -> Vec<Out4> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Out4> {
    inputs
        .into_par()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Out4> {
    inputs
        .into_par()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_long_chain");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().map(map).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs.into_par().map(map).collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs.into_par().map(map).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Vec<Output> {
    inputs.iter().map(map).filter(filter).collect()
}

fn rayon(inputs: &[usize]) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).filter(filter).collect()
}

fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
    inputs.into_par().map(map).filter(filter).collect()
}

fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
    inputs.into_par().map(map).filter(filter).collect()
}

#[allow(dead_code)]
fn orx_into_vec_with<P: ParThreadPool>(inputs: &[usize], pool: P) -> Vec<Output> {
    inputs
        .into_par()
        .with_pool(pool)
        .map(map)
        .filter(filter)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_map_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&input));
            b.iter(|| orx_into_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&input));
            b.iter(|| orx_into_split_vec(black_box(&input)))
        });

        #[cfg(feature = "rayon-core")]
        group.bench_with_input(
            BenchmarkId::new("orx-into-vec (rayon-core::ThreadPool)", n),
            n,
            |b, _| {
                let pool = rayon_core::ThreadPoolBuilder::new()
                    .num_threads(32)
                    .build()
                    .unwrap();
                assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
                b.iter(|| orx_into_vec_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "scoped-pool")]
        group.bench_with_input(
            BenchmarkId::new("orx-into-vec (scoped-pool::Pool)", n),
            n,
            |b, _| {
                let pool = scoped_pool::Pool::new(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
                b.iter(|| orx_into_vec_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "scoped_threadpool")]
        group.bench_with_input(
            BenchmarkId::new("orx-into-vec (scoped_threadpool::Pool)", n),
            n,
            |b, _| {
                let pool = || scoped_threadpool::Pool::new(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, pool()));
                b.iter(|| orx_into_vec_with(black_box(&input), pool()))
            },
        );

        #[cfg(feature = "yastl")]
        group.bench_with_input(
            BenchmarkId::new("orx-into-vec (yastl::Pool)", n),
            n,
            |b, _| {
                let pool = YastlPool::new(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, &pool));
                b.iter(|| orx_into_vec_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "pond")]
        group.bench_with_input(
            BenchmarkId::new("orx-into-vec (pond::Pool)", n),
            n,
            |b, _| {
                let pool = || PondPool::new_threads_unbounded(32);
                assert_eq!(&expected, &orx_into_vec_with(&input, pool()));
                b.iter(|| orx_into_vec_with(black_box(&input), pool()))
            },
        );
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/collect_map_filter_hash_set.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::collections::HashSet;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> HashSet<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &HashSet<usize>) -> Vec<Output> {
    inputs.iter().map(map).filter(filter).collect()
}

fn rayon(inputs: &HashSet<usize>) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).filter(filter).collect()
}

fn orx_through_vec(inputs: &HashSet<usize>) -> Vec<Output> {
    let inputs: Vec<_> = inputs.iter().collect();
    inputs.into_par().map(map).filter(filter).collect()
}

fn orx_through_iter(inputs: &HashSet<usize>) -> Vec<Output> {
    inputs
        .iter()
        .iter_into_par()
        .map(map)
        .filter(filter)
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_map_filter_hash_set");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);
        let mut sorted = seq(&input);
        sorted.sort();

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-through-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_through_vec(&input));
            b.iter(|| orx_through_vec(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx-through-iter", n), n, |b, _| {
            assert_eq!(&expected, &orx_through_iter(&input));
            b.iter(|| orx_through_iter(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/count_filtermap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn filter_map(idx: &usize) -> Option<Output> {
    idx.is_multiple_of(3).then(|| to_output(idx))
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> usize {
    inputs.iter().filter_map(filter_map).count()
}

fn rayon(inputs: &[usize]) -> usize {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().filter_map(filter_map).count()
}

fn orx(inputs: &[usize]) -> usize {
    inputs.into_par().filter_map(filter_map).count()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("count_filtermap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/count_flatmap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = true;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn flat_map(idx: &usize) -> Vec<Output> {
    (0..4).map(|i| to_output(&(idx + i))).collect::<Vec<_>>()
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> usize {
    inputs.iter().flat_map(flat_map).count()
}

fn rayon(inputs: &[usize]) -> usize {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().flat_map(flat_map).count()
}

fn orx(inputs: &[usize]) -> usize {
    inputs.into_par().flat_map(flat_map).count()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("count_flatmap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/count_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> usize {
    inputs.iter().map(map).count()
}

fn rayon(inputs: &[usize]) -> usize {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).count()
}

fn orx(inputs: &[usize]) -> usize {
    inputs.into_par().map(map).count()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("count_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/count_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = true;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> usize {
    inputs.iter().map(map).filter(filter).count()
}

fn rayon(inputs: &[usize]) -> usize {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).filter(filter).count()
}

fn orx(inputs: &[usize]) -> usize {
    inputs.into_par().map(map).filter(filter).count()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("count_map_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/drain_vec_collect_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: usize) -> Output {
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(output: &Output) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(input: &mut Vec<usize>) -> Vec<Output> {
    input.drain(..).map(map).filter(filter).collect()
}

fn rayon(input: &mut Vec<usize>) -> Vec<Output> {
    use rayon::iter::ParallelIterator;
    rayon::iter::ParallelDrainRange::par_drain(input, ..)
        .map(map)
        .filter(filter)
        .collect()
}

fn orx_into_vec(input: &mut Vec<usize>) -> Vec<Output> {
    input.par_drain(..).map(map).filter(filter).collect()
}

fn orx_into_split_vec(input: &mut Vec<usize>) -> SplitVec<Output> {
    input.par_drain(..).map(map).filter(filter).collect()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("drain_vec_collect_map_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&mut input.clone());

        group.bench_with_input(BenchmarkId::new("seq-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &seq(&mut input.clone()));
            b.iter(|| seq(black_box(&mut input.clone())))
        });

        group.bench_with_input(BenchmarkId::new("rayon-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&mut input.clone()));
            b.iter(|| rayon(black_box(&mut input.clone())))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_vec(&mut input.clone()));
            b.iter(|| orx_into_vec(black_box(&mut input.clone())))
        });

        group.bench_with_input(BenchmarkId::new("orx-into-split-vec", n), n, |b, _| {
            assert_eq!(&expected, &orx_into_split_vec(&mut input.clone()));
            b.iter(|| orx_into_split_vec(black_box(&mut input.clone())))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/find.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Output { id, name, numbers }
}

fn get_find(n: usize) -> impl Fn(&Output) -> bool {
    move |a: &Output| a.id.parse::<usize>().unwrap() == n
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<Output> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .map(|x| to_output(&x))
        .collect()
}

fn seq(inputs: &[Output], find: impl Fn(&Output) -> bool) -> Option<&Output> {
    inputs.iter().find(|x| find(x))
}

fn rayon(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<&Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().find_first(|x| find(x))
}

fn orx(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<&Output> {
    inputs.into_par().find(|x| find(x))
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("find");

    for n_when in &treatments {
        let find = get_find(*n_when);
        let input = inputs(N);
        let expected = seq(&input, &find);

        let n_when = match *n_when {
            N_EARLY => "find-early",
            N_MIDDLE => "find-in-the-middle",
            N_LATE => "find-late",
            N_NEVER => "find-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, &find));
            b.iter(|| seq(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, &find));
            b.iter(|| rayon(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, &find));
            b.iter(|| orx(black_box(&input), &find))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/find_any.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Output { id, name, numbers }
}

fn get_find(n: usize) -> impl Fn(&Output) -> bool {
    move |a: &Output| a.id.parse::<usize>().unwrap() == n
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<Output> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .map(|x| to_output(&x))
        .collect()
}

fn seq(inputs: &[Output], find: impl Fn(&Output) -> bool) -> Option<&Output> {
    inputs.iter().find(|x| find(x))
}

fn rayon(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<&Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().find_any(|x| find(x))
}

fn orx(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<&Output> {
    inputs
        .into_par()
        .iteration_order(IterationOrder::Arbitrary)
        .find(|x| find(x))
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("find_any");

    for n_when in &treatments {
        let find = get_find(*n_when);
        let input = inputs(N);
        let expected = seq(&input, &find);

        let n_when = match *n_when {
            N_EARLY => "find-early",
            N_MIDDLE => "find-in-the-middle",
            N_LATE => "find-late",
            N_NEVER => "find-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, &find));
            b.iter(|| seq(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, &find));
            b.iter(|| rayon(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, &find));
            b.iter(|| orx(black_box(&input), &find))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/find_flatmap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn flat_map(idx: &usize) -> Vec<Output> {
    (0..4).map(|i| to_output(&(idx + i))).collect::<Vec<_>>()
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Output { id, name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn get_find(n: usize) -> impl Fn(&Output) -> bool {
    move |a: &Output| a.id.parse::<usize>().unwrap() == n
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    inputs.iter().flat_map(flat_map).find(find)
}

fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().flat_map(flat_map).find_first(find)
}

fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    inputs.into_par().flat_map(flat_map).find(&find)
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("find_flatmap");

    for n_when in &treatments {
        let find = get_find(*n_when);
        let input = inputs(N);
        let expected = seq(&input, &find);

        let n_when = match *n_when {
            N_EARLY => "find-early",
            N_MIDDLE => "find-in-the-middle",
            N_LATE => "find-late",
            N_NEVER => "find-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, &find));
            b.iter(|| seq(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, &find));
            b.iter(|| rayon(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, &find));
            b.iter(|| orx(black_box(&input), &find))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/find_iter_into_par.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::ParallelBridge;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Output { id, name, numbers }
}

fn get_find(n: usize) -> impl Fn(&Output) -> bool {
    move |a: &Output| a.id.parse::<usize>().unwrap() == n
}

fn filter(a: &Output) -> bool {
    !a.name.ends_with('1')
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool) -> Option<Output> {
    inputs.iter().map(map).filter(filter).find(find)
}

fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .iter()
        .par_bridge()
        .map(map)
        .filter(filter)
        .find_first(find)
}

fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    inputs
        .iter()
        .iter_into_par()
        .map(map)
        .filter(filter)
        .find(&find)
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("find_iter_into_par");

    for n_when in &treatments {
        let find = get_find(*n_when);
        let input = inputs(N);
        let expected = seq(&input, &find);

        let n_when = match *n_when {
            N_EARLY => "find-early",
            N_MIDDLE => "find-in-the-middle",
            N_LATE => "find-late",
            N_NEVER => "find-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, &find));
            b.iter(|| seq(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, &find));
            b.iter(|| rayon(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, &find));
            b.iter(|| orx(black_box(&input), &find))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/find_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Output { id, name, numbers }
}

fn get_find(n: usize) -> impl Fn(&Output) -> bool {
    move |a: &Output| a.id.parse::<usize>().unwrap() == n
}

fn filter(a: &Output) -> bool {
    !a.name.ends_with('1')
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool) -> Option<Output> {
    inputs.iter().map(map).filter(filter).find(find)
}

fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .map(map)
        .filter(filter)
        .find_first(find)
}

fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -> Option<Output> {
    inputs.into_par().map(map).filter(filter).find(&find)
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("find_map_filter");

    for n_when in &treatments {
        let find = get_find(*n_when);
        let input = inputs(N);
        let expected = seq(&input, &find);

        let n_when = match *n_when {
            N_EARLY => "find-early",
            N_MIDDLE => "find-in-the-middle",
            N_LATE => "find-late",
            N_NEVER => "find-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, &find));
            b.iter(|| seq(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, &find));
            b.iter(|| rayon(black_box(&input), &find))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, &find));
            b.iter(|| orx(black_box(&input), &find))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/mut_for_each_iter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::collections::HashMap;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
struct Data {
    name: String,
    number: usize,
}

fn to_output(idx: usize) -> Data {
    let name = idx.to_string();
    let number = idx;
    Data { name, number }
}

fn inputs(len: usize) -> HashMap<usize, Data> {
    (0..len).map(|i| (i, to_output(i))).collect()
}

fn fibonacci(n: usize) -> usize {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn filter(data: &&mut Data) -> bool {
    !data.name.starts_with('3')
}

fn update(data: &mut Data) {
    for _ in 0..50 {
        let increment = fibonacci(data.number % 100) % 10;
        data.number += increment
    }
}

fn seq<'a>(inputs: impl Iterator<Item = &'a mut Data>) {
    inputs.filter(filter).for_each(update);
}

fn rayon<'a>(inputs: impl Iterator<Item = &'a mut Data> + Send) {
    use rayon::iter::{ParallelBridge, ParallelIterator};
    inputs.par_bridge().filter(filter).for_each(update);
}

fn orx<'a>(inputs: impl Iterator<Item = &'a mut Data>) {
    use orx_parallel::*;
    inputs.iter_into_par().filter(filter).for_each(update);
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("mut_for_each_iter");

    for n in &treatments {
        let input = inputs(*n);
        let mut expected = input.clone();
        seq(expected.values_mut());
        let expected = expected;

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            let mut input = input.clone();
            seq(input.values_mut());
            assert_eq!(expected, input);
            b.iter(|| seq(input.values_mut()))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            let mut input = input.clone();
            rayon(input.values_mut());
            assert_eq!(expected, input);
            b.iter(|| rayon(input.values_mut()))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            let mut input = input.clone();
            orx(input.values_mut());
            assert_eq!(expected, input);
            b.iter(|| orx(input.values_mut()))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/mut_for_each_slice.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::hint::black_box;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
struct Data {
    name: String,
    number: usize,
}

fn to_output(idx: usize) -> Data {
    let name = idx.to_string();
    let number = idx;
    Data { name, number }
}

fn inputs(len: usize) -> Vec<Data> {
    (0..len).map(to_output).collect()
}

fn fibonacci(n: usize) -> usize {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn filter(data: &&mut Data) -> bool {
    !data.name.starts_with('3')
}

fn update(data: &mut Data) {
    for _ in 0..50 {
        let increment = fibonacci(data.number % 100) % 10;
        data.number += increment
    }
}

fn seq(inputs: &mut [Data]) {
    inputs.iter_mut().filter(filter).for_each(update);
}

fn rayon(inputs: &mut [Data]) {
    use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
    inputs.par_iter_mut().filter(filter).for_each(update);
}

fn orx(inputs: &mut [Data]) {
    use orx_parallel::*;
    inputs.into_par().filter(filter).for_each(update);
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("mut_for_each_slice");

    for n in &treatments {
        let input = inputs(*n);
        let mut expected = input.clone();
        seq(&mut expected);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            let mut input = input.clone();
            seq(&mut input);
            assert_eq!(expected, input);
            b.iter(|| seq(black_box(&mut input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            let mut input = input.clone();
            seq(&mut input);
            assert_eq!(expected, input);
            b.iter(|| rayon(black_box(&mut input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            let mut input = input.clone();
            seq(&mut input);
            assert_eq!(expected, input);
            b.iter(|| orx(black_box(&mut input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/rec_iter_map_collect.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_concurrent_recursive_iter::Queue;
use orx_parallel::*;
use orx_split_vec::SplitVec;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use std::hint::black_box;

fn fibonacci(n: u64, work: usize) -> u64 {
    (7..(work + 7))
        .map(|j| {
            let n = black_box((n + j as u64) % 100);
            let mut a = 0;
            let mut b = 1;
            for _ in 0..n {
                let c = a + b;
                a = b;
                b = c;
            }
            a
        })
        .sum()
}

struct Node {
    value: Vec<u64>,
    children: Vec<Node>,
}

impl Node {
    fn new(mut n: u32, rng: &mut impl Rng) -> Self {
        let mut children = Vec::new();
        if n < 5 {
            for _ in 0..n {
                children.push(Node::new(0, rng));
            }
        } else {
            while n > 0 {
                let n2 = rng.random_range(0..=n);
                children.push(Node::new(n2, rng));
                n -= n2;
            }
        }
        Self {
            value: (0..rng.random_range(1..500))
                .map(|_| rng.random_range(0..40))
                .collect(),
            children,
        }
    }

    fn seq_num_nodes(&self) -> usize {
        1 + self
            .children
            .iter()
            .map(|node| node.seq_num_nodes())
            .sum::<usize>()
    }

    fn seq(&self, work: usize, numbers: &mut Vec<u64>) {
        numbers.extend(self.value.iter().map(|x| fibonacci(*x, work)));
        for c in &self.children {
            c.seq(work, numbers);
        }
    }
}

// alternatives

fn seq(roots: &[Node], work: usize) -> Vec<u64> {
    let mut result = vec![];
    for root in roots {
        root.seq(work, &mut result);
    }
    result
}

fn orx_lazy_unknown_chunk1024(roots: &[Node], work: usize) -> SplitVec<u64> {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec(extend)
        .chunk_size(1024)
        .flat_map(|x| x.value.iter().map(|x| fibonacci(*x, work)))
        .collect()
}

fn orx_lazy_exact(roots: &[Node], work: usize, num_nodes: usize) -> SplitVec<u64> {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec_exact(extend, num_nodes)
        .flat_map(|x| x.value.iter().map(|x| fibonacci(*x, work)))
        .collect()
}

fn orx_linearized(roots: &[Node], work: usize) -> SplitVec<u64> {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec(extend)
        .linearize()
        .flat_map(|x| x.value.iter().map(|x| fibonacci(*x, work)))
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [1, 10, 25];
    let mut group = c.benchmark_group("rec_iter_map_collect");
    let mut rng = ChaCha8Rng::seed_from_u64(42);
    let roots = vec![
        Node::new(5000, &mut rng),
        Node::new(2000, &mut rng),
        Node::new(4000, &mut rng),
    ];

    let num_nodes: usize = roots.iter().map(|x| x.seq_num_nodes()).sum();

    for work in &treatments {
        let mut expected = seq(&roots, *work);
        expected.sort();

        group.bench_with_input(BenchmarkId::new("seq", work), work, |b, _| {
            let mut result = seq(&roots, *work);
            result.sort();
            assert_eq!(&expected, &result);
            b.iter(|| seq(&roots, *work))
        });

        group.bench_with_input(BenchmarkId::new("orx_lazy_exact", work), work, |b, _| {
            let mut result = orx_lazy_exact(&roots, *work, num_nodes).to_vec();
            result.sort();
            assert_eq!(&expected, &result);
            b.iter(|| orx_lazy_exact(&roots, *work, num_nodes))
        });

        group.bench_with_input(
            BenchmarkId::new("orx_lazy_unknown_chunk1024", work),
            work,
            |b, _| {
                let mut result = orx_lazy_unknown_chunk1024(&roots, *work).to_vec();
                result.sort();
                assert_eq!(&expected, &result);
                b.iter(|| orx_lazy_unknown_chunk1024(&roots, *work))
            },
        );

        group.bench_with_input(BenchmarkId::new("orx_linearized", work), work, |b, _| {
            let mut result = orx_linearized(&roots, *work).to_vec();
            result.sort();
            assert_eq!(&expected, &result);
            b.iter(|| orx_linearized(&roots, *work))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/rec_iter_map_sum.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_concurrent_recursive_iter::Queue;
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use std::{
    hint::black_box,
    sync::atomic::{AtomicU64, Ordering},
};

fn fibonacci(n: u64, work: usize) -> u64 {
    (7..(work + 7))
        .map(|j| {
            let n = black_box((n + j as u64) % 100);
            let mut a = 0;
            let mut b = 1;
            for _ in 0..n {
                let c = a + b;
                a = b;
                b = c;
            }
            a
        })
        .sum()
}

struct Node {
    value: Vec<u64>,
    children: Vec<Node>,
}

impl Node {
    fn new(mut n: u32, rng: &mut impl Rng) -> Self {
        let mut children = Vec::new();
        if n < 5 {
            for _ in 0..n {
                children.push(Node::new(0, rng));
            }
        } else {
            while n > 0 {
                let n2 = rng.random_range(0..=n);
                children.push(Node::new(n2, rng));
                n -= n2;
            }
        }
        Self {
            value: (0..rng.random_range(1..500))
                .map(|_| rng.random_range(0..40))
                .collect(),
            children,
        }
    }

    fn seq_num_nodes(&self) -> usize {
        1 + self
            .children
            .iter()
            .map(|node| node.seq_num_nodes())
            .sum::<usize>()
    }

    fn seq_sum_fib(&self, work: usize) -> u64 {
        self.value.iter().map(|x| fibonacci(*x, work)).sum::<u64>()
            + self
                .children
                .iter()
                .map(|x| x.seq_sum_fib(work))
                .sum::<u64>()
    }
}

// alternatives

fn seq(roots: &[Node], work: usize) -> u64 {
    roots.iter().map(|x| x.seq_sum_fib(work)).sum()
}

fn rayon(roots: &[Node], work: usize) -> u64 {
    use rayon::iter::*;
    fn process_node<'scope>(
        work: usize,
        sum: &'scope AtomicU64,
        node: &'scope Node,
        s: &rayon::Scope<'scope>,
    ) {
        for child in &node.children {
            s.spawn(move |s| {
                process_node(work, sum, child, s);
            });
        }
        let val = node.value.par_iter().map(|x| fibonacci(*x, work)).sum();
        sum.fetch_add(val, Ordering::Relaxed);
    }

    let sum = AtomicU64::new(0);
    rayon::in_place_scope(|s| {
        for root in roots {
            process_node(work, &sum, root, s);
        }
    });
    sum.into_inner()
}

fn orx_lazy_unknown_chunk1024(roots: &[Node], work: usize) -> u64 {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec(extend)
        .chunk_size(1024)
        .map(|x| x.value.iter().map(|x| fibonacci(*x, work)).sum::<u64>())
        .sum()
}

fn orx_lazy_exact(roots: &[Node], work: usize, num_nodes: usize) -> u64 {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec_exact(extend, num_nodes)
        .map(|x| x.value.iter().map(|x| fibonacci(*x, work)).sum::<u64>())
        .sum()
}

fn orx_lazy_exact_flat_map(roots: &[Node], work: usize, num_nodes: usize) -> u64 {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec_exact(extend, num_nodes)
        .flat_map(|x| x.value.iter().map(|x| fibonacci(*x, work)))
        .sum()
}

fn orx_linearized(roots: &[Node], work: usize) -> u64 {
    fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) {
        queue.extend(&node.children);
    }

    roots
        .into_par_rec(extend)
        .linearize()
        .map(|x| x.value.iter().map(|x| fibonacci(*x, work)).sum::<u64>())
        .sum()
}

fn run(c: &mut Criterion) {
    let treatments = [1, 10, 25];
    let mut group = c.benchmark_group("rec_iter_map_sum");
    let mut rng = ChaCha8Rng::seed_from_u64(42);
    let roots = vec![
        Node::new(5000, &mut rng),
        Node::new(2000, &mut rng),
        Node::new(4000, &mut rng),
    ];

    let num_nodes: usize = roots.iter().map(|x| x.seq_num_nodes()).sum();

    for work in &treatments {
        let expected = seq(&roots, *work);

        group.bench_with_input(BenchmarkId::new("seq", work), work, |b, _| {
            assert_eq!(&expected, &seq(&roots, *work));
            b.iter(|| seq(&roots, *work))
        });

        group.bench_with_input(BenchmarkId::new("rayon", work), work, |b, _| {
            assert_eq!(&expected, &rayon(&roots, *work));
            b.iter(|| rayon(&roots, *work))
        });

        group.bench_with_input(
            BenchmarkId::new("orx_lazy_unknown_chunk1024", work),
            work,
            |b, _| {
                assert_eq!(&expected, &orx_lazy_unknown_chunk1024(&roots, *work));
                b.iter(|| orx_lazy_unknown_chunk1024(&roots, *work))
            },
        );

        group.bench_with_input(BenchmarkId::new("orx_lazy_exact", work), work, |b, _| {
            assert_eq!(&expected, &orx_lazy_exact(&roots, *work, num_nodes));
            b.iter(|| orx_lazy_exact(&roots, *work, num_nodes))
        });

        group.bench_with_input(
            BenchmarkId::new("orx_lazy_exact_flat_map", work),
            work,
            |b, _| {
                assert_eq!(
                    &expected,
                    &orx_lazy_exact_flat_map(&roots, *work, num_nodes)
                );
                b.iter(|| orx_lazy_exact_flat_map(&roots, *work, num_nodes))
            },
        );

        group.bench_with_input(BenchmarkId::new("orx_linearized", work), work, |b, _| {
            assert_eq!(&expected, &orx_linearized(&roots, *work));
            b.iter(|| orx_linearized(&roots, *work))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/reduce.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn reduce<'a>(a: &'a Output, b: &'a Output) -> &'a Output {
    match a.name < b.name {
        true => a,
        false => b,
    }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<Output> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .map(|x| to_output(&x))
        .collect()
}

fn seq(inputs: &[Output]) -> Option<&Output> {
    inputs.iter().reduce(reduce)
}

fn rayon(inputs: &[Output]) -> Option<&Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().reduce_with(reduce)
}

fn orx(inputs: &[Output]) -> Option<&Output> {
    inputs.into_par().reduce(reduce)
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("reduce");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/reduce_iter_into_par.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::ParallelBridge;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(a: &Output) -> bool {
    !a.name.ends_with('1')
}

fn reduce(a: Output, b: Output) -> Output {
    match a.name < b.name {
        true => a,
        false => b,
    }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Option<Output> {
    inputs.iter().map(map).filter(filter).reduce(reduce)
}

fn rayon(inputs: &[usize]) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .iter()
        .map(map)
        .filter(filter)
        .par_bridge()
        .reduce_with(reduce)
}

fn orx(inputs: &[usize]) -> Option<Output> {
    inputs
        .iter()
        .iter_into_par()
        .map(map)
        .filter(filter)
        .reduce(reduce)
}

#[allow(dead_code)]
fn orx_with<P: ParThreadPool>(inputs: &[usize], pool: P) -> Option<Output> {
    inputs
        .iter()
        .iter_into_par()
        .with_pool(pool)
        .map(map)
        .filter(filter)
        .reduce(reduce)
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("reduce_iter_into_par");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });

        #[cfg(feature = "rayon-core")]
        group.bench_with_input(
            BenchmarkId::new("orx (rayon-core::ThreadPool)", n),
            n,
            |b, _| {
                let pool = rayon_core::ThreadPoolBuilder::new()
                    .num_threads(32)
                    .build()
                    .unwrap();
                assert_eq!(&expected, &orx_with(&input, &pool));
                b.iter(|| orx_with(black_box(&input), &pool))
            },
        );

        #[cfg(feature = "scoped-pool")]
        group.bench_with_input(BenchmarkId::new("orx (scoped-pool::Pool)", n), n, |b, _| {
            let pool = scoped_pool::Pool::new(32);
            assert_eq!(&expected, &orx_with(&input, &pool));
            b.iter(|| orx_with(black_box(&input), &pool))
        });

        #[cfg(feature = "scoped_threadpool")]
        group.bench_with_input(
            BenchmarkId::new("orx (scoped_threadpool::Pool)", n),
            n,
            |b, _| {
                let pool = || scoped_threadpool::Pool::new(32);
                assert_eq!(&expected, &orx_with(&input, pool()));
                b.iter(|| orx_with(black_box(&input), pool()))
            },
        );

        #[cfg(feature = "yastl")]
        group.bench_with_input(BenchmarkId::new("orx (yastl::Pool)", n), n, |b, _| {
            let pool = YastlPool::new(32);
            assert_eq!(&expected, &orx_with(&input, &pool));
            b.iter(|| orx_with(black_box(&input), &pool))
        });

        #[cfg(feature = "pond")]
        group.bench_with_input(BenchmarkId::new("orx (pond::Pool)", n), n, |b, _| {
            let pool = || PondPool::new_threads_unbounded(32);
            assert_eq!(&expected, &orx_with(&input, pool()));
            b.iter(|| orx_with(black_box(&input), pool()))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/reduce_long_chain.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 29;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out1 {
    name: String,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out2 {
    name: String,
    number: u32,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out3 {
    out2: Out2,
    fib: u32,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Out4 {
    a: String,
    b: char,
    fib: u32,
}

fn map1(idx: &usize) -> Out1 {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32 % FIB_UPPER_BOUND));
    let name = format!("{}-fib-{}", prefix, fib);
    Out1 { name }
}

fn filter1(output: &Out1) -> bool {
    let last_char = output.name.chars().last().unwrap();
    let last_digit: u32 = last_char.to_string().parse().unwrap();
    last_digit < 4
}

fn map2(input: Out1) -> Out2 {
    let number = (FIB_UPPER_BOUND + input.name.len() as u32).saturating_sub(10);
    let number = fibonacci(&(number & FIB_UPPER_BOUND));
    Out2 {
        name: number.to_string(),
        number,
    }
}

fn filter2(output: &Out2) -> bool {
    output.number.is_multiple_of(2) || output.name.contains('0')
}

fn map3(input: Out2) -> Out3 {
    let fib = fibonacci(&input.number);
    Out3 { out2: input, fib }
}

fn map4(input: Out3) -> Out4 {
    let a = format!("{}!", input.out2.name);
    let b = input.out2.name.chars().next().unwrap();
    let fib = fibonacci(&((input.out2.number * 7) % FIB_UPPER_BOUND));
    Out4 { a, b, fib }
}

fn filter4(output: &Out4) -> bool {
    output.a.len() == 5 || output.b == 'x' || output.fib % 2 == 1
}

fn reduce(x: Out4, y: Out4) -> Out4 {
    let a = match x.fib.is_multiple_of(2) {
        true => x.a,
        false => y.a,
    };
    let b = match y.fib.is_multiple_of(2) {
        true => x.b,
        false => y.b,
    };
    let fib = x.fib + y.fib;
    Out4 { a, b, fib }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Option<Out4> {
    inputs
        .iter()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .reduce(reduce)
}

fn rayon(inputs: &[usize]) -> Option<Out4> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .reduce_with(reduce)
}

fn orx(inputs: &[usize]) -> Option<Out4> {
    inputs
        .into_par()
        .map(map1)
        .filter(filter1)
        .map(map2)
        .filter(filter2)
        .map(map3)
        .map(map4)
        .filter(filter4)
        .reduce(reduce)
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("collect_long_chain");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/reduce_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn reduce(a: Output, b: Output) -> Output {
    match a.name < b.name {
        true => a,
        false => b,
    }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Option<Output> {
    inputs.iter().map(map).reduce(reduce)
}

fn rayon(inputs: &[usize]) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).reduce_with(reduce)
}

fn orx(inputs: &[usize]) -> Option<Output> {
    inputs.into_par().map(map).reduce(reduce)
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("reduce_map");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/reduce_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn map(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn filter(a: &Output) -> bool {
    !a.name.ends_with('1')
}

fn reduce(a: Output, b: Output) -> Output {
    match a.name < b.name {
        true => a,
        false => b,
    }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> Option<Output> {
    inputs.iter().map(map).filter(filter).reduce(reduce)
}

fn rayon(inputs: &[usize]) -> Option<Output> {
    use rayon::iter::ParallelIterator;
    inputs
        .into_par_iter()
        .map(map)
        .filter(filter)
        .reduce_with(reduce)
}

fn orx(inputs: &[usize]) -> Option<Output> {
    inputs.into_par().map(map).filter(filter).reduce(reduce)
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("reduce_map_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/result_collect_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use std::hint::black_box;
use std::num::ParseIntError;

type Err = ParseIntError;

const TEST_LARGE_OUTPUT: bool = false;
const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Input {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_input(idx: &usize) -> Input {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Input { id, name, numbers }
}

fn to_bad_input() -> Input {
    Input {
        id: "xyz".to_string(),
        name: "xyz".to_string(),
        numbers: Default::default(),
    }
}

fn map_input_to_result(input: &Input) -> Result<String, Err> {
    match input.id.parse::<usize>() {
        Ok(_) => Ok(input.id.clone()),
        Err(e) => Err(e),
    }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize, idx_error: usize) -> Vec<Input> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|i| match i == idx_error {
            true => to_bad_input(),
            false => {
                let x = rng.random_range(0..FIB_UPPER_BOUND) as usize;
                to_input(&x)
            }
        })
        .collect()
}

fn seq(inputs: &[Input], map: impl Fn(&Input) -> Result<String, Err>) -> Result<Vec<String>, Err> {
    inputs.iter().map(map).collect()
}

fn rayon(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Send,
) -> Result<Vec<String>, Err> {
    use rayon::iter::*;
    inputs.into_par_iter().map(map).collect()
}

fn orx(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Clone,
) -> Result<Vec<String>, Err> {
    use orx_parallel::*;
    inputs.into_par().map(map).into_fallible_result().collect()
}

fn orx_arbitrary(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Clone,
) -> Result<Vec<String>, Err> {
    use orx_parallel::*;
    inputs
        .into_par()
        .iteration_order(IterationOrder::Arbitrary)
        .map(map)
        .into_fallible_result()
        .collect()
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("result_collect_map");

    for n_when in &treatments {
        let input = inputs(N, *n_when);
        let expected = seq(&input, map_input_to_result);

        let n_when = match *n_when {
            N_EARLY => "error-early",
            N_MIDDLE => "error-in-the-middle",
            N_LATE => "error-late",
            N_NEVER => "error-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, map_input_to_result));
            b.iter(|| seq(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, map_input_to_result));
            b.iter(|| rayon(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, map_input_to_result));
            b.iter(|| orx(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("orx_arbitrary", n_when), n_when, |b, _| {
            assert_eq!(
                expected.as_ref().map(|x| x.len()),
                orx_arbitrary(&input, map_input_to_result)
                    .as_ref()
                    .map(|x| x.len())
            );
            b.iter(|| orx_arbitrary(black_box(&input), map_input_to_result))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/result_reduce_map.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_concurrent_option::{ConcurrentOption, IntoOption};
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use std::hint::black_box;
use std::num::ParseIntError;

type Err = ParseIntError;

const TEST_LARGE_OUTPUT: bool = false;
const N: usize = 65_536 * 4;
const N_EARLY: usize = 1000;
const N_MIDDLE: usize = 65_536 * 2;
const N_LATE: usize = 65_536 * 4 - 10;
const N_NEVER: usize = usize::MAX;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Input {
    id: String,
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn to_input(idx: &usize) -> Input {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    let id = idx.to_string();

    Input { id, name, numbers }
}

fn to_bad_input() -> Input {
    Input {
        id: "xyz".to_string(),
        name: "xyz".to_string(),
        numbers: Default::default(),
    }
}

fn map_input_to_result(input: &Input) -> Result<String, Err> {
    match input.id.parse::<usize>() {
        Ok(_) => Ok(input.id.clone()),
        Err(e) => Err(e),
    }
}

fn map_to_number(a: String) -> u32 {
    let num = a.parse::<u32>().unwrap();
    fibonacci(&(num % 72))
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize, idx_error: usize) -> Vec<Input> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|i| match i == idx_error {
            true => to_bad_input(),
            false => {
                let x = rng.random_range(0..FIB_UPPER_BOUND) as usize;
                to_input(&x)
            }
        })
        .collect()
}

fn seq(inputs: &[Input], map: impl Fn(&Input) -> Result<String, Err>) -> Result<Option<u32>, Err> {
    let mut error = None;
    let sum = inputs
        .iter()
        .map(map)
        .inspect(|x| {
            if let Err(e) = x {
                error = Some(e.clone());
            }
        })
        .take_while(|x| x.is_ok())
        .map(|x| map_to_number(x.unwrap()))
        .reduce(|a, b| a + b);

    match error {
        Some(error) => Err(error),
        None => Ok(sum),
    }
}

fn rayon(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Send,
) -> Result<Option<u32>, Err> {
    use rayon::iter::*;
    let error = ConcurrentOption::none();
    let sum = inputs
        .into_par_iter()
        .map(map)
        .inspect(|x| {
            if let Err(e) = x {
                error.set_some(e.clone());
            }
        })
        .map(|x| x.ok())
        .while_some()
        .map(map_to_number)
        .reduce_with(|a, b| a + b);

    match error.into_option() {
        Some(error) => Err(error),
        None => Ok(sum),
    }
}

fn orx(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Clone,
) -> Result<Option<u32>, Err> {
    use orx_parallel::*;
    inputs
        .into_par()
        .map(map)
        .into_fallible_result()
        .map(map_to_number)
        .reduce(|a, b| a + b)
}

fn orx_arbitrary(
    inputs: &[Input],
    map: impl Fn(&Input) -> Result<String, Err> + Sync + Clone,
) -> Result<Option<u32>, Err> {
    use orx_parallel::*;
    inputs
        .into_par()
        .iteration_order(IterationOrder::Arbitrary)
        .map(map)
        .into_fallible_result()
        .map(map_to_number)
        .reduce(|a, b| a + b)
}

fn run(c: &mut Criterion) {
    let treatments = [N_EARLY, N_MIDDLE, N_LATE, N_NEVER];

    let mut group = c.benchmark_group("result_reduce_map");

    for n_when in &treatments {
        let input = inputs(N, *n_when);
        let expected = seq(&input, map_input_to_result);

        let n_when = match *n_when {
            N_EARLY => "error-early",
            N_MIDDLE => "error-in-the-middle",
            N_LATE => "error-late",
            N_NEVER => "error-never",
            _ => panic!("unhandled n-when"),
        };

        group.bench_with_input(BenchmarkId::new("seq", n_when), n_when, |b, _| {
            assert_eq!(&expected, &seq(&input, map_input_to_result));
            b.iter(|| seq(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n_when), n_when, |b, _| {
            assert_eq!(&expected, &rayon(&input, map_input_to_result));
            b.iter(|| rayon(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("orx", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx(&input, map_input_to_result));
            b.iter(|| orx(black_box(&input), map_input_to_result))
        });

        group.bench_with_input(BenchmarkId::new("orx_arbitrary", n_when), n_when, |b, _| {
            assert_eq!(&expected, &orx_arbitrary(&input, map_input_to_result));
            b.iter(|| orx_arbitrary(black_box(&input), map_input_to_result))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/sum.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

fn to_output(idx: &usize) -> u32 {
    let idx = *idx;
    fibonacci(&(idx as u32))
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<u32> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .map(|x| to_output(&x))
        .collect()
}

fn seq(inputs: &[u32]) -> u32 {
    inputs.iter().sum()
}

fn rayon(inputs: &[u32]) -> u32 {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().sum()
}

fn orx(inputs: &[u32]) -> u32 {
    inputs.into_par().sum()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("sum");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/sum_filtermap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn filter_map(idx: &usize) -> Option<u64> {
    idx.is_multiple_of(3)
        .then(|| to_output(idx))
        .map(|x| x.name.len() as u64)
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> u64 {
    inputs.iter().filter_map(filter_map).sum()
}

fn rayon(inputs: &[usize]) -> u64 {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().filter_map(filter_map).sum()
}

fn orx(inputs: &[usize]) -> u64 {
    inputs.into_par().filter_map(filter_map).sum()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("sum_filtermap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/sum_flatmap.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const TEST_LARGE_OUTPUT: bool = false;

const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
    true => 64,
    false => 0,
};
const SEED: u64 = 9562;
const FIB_UPPER_BOUND: u32 = 201;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Output {
    name: String,
    numbers: [i64; LARGE_OUTPUT_LEN],
}

fn flat_map(idx: &usize) -> Vec<u64> {
    (0..4)
        .map(|i| to_output(&(idx + i)))
        .map(|x| x.name.len() as u64)
        .collect::<Vec<_>>()
}

fn to_output(idx: &usize) -> Output {
    let idx = *idx;
    let prefix = match idx % 7 {
        0 => "zero-",
        3 => "three-",
        _ => "sth-",
    };
    let fib = fibonacci(&(idx as u32));
    let name = format!("{}-fib-{}", prefix, fib);

    let mut numbers = [0i64; LARGE_OUTPUT_LEN];
    for (i, x) in numbers.iter_mut().enumerate() {
        *x = match (idx * 7 + i) % 3 {
            0 => idx as i64 + i as i64,
            _ => idx as i64 - i as i64,
        };
    }

    Output { name, numbers }
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> u64 {
    inputs.iter().flat_map(flat_map).sum()
}

fn rayon(inputs: &[usize]) -> u64 {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().flat_map(flat_map).sum()
}

fn orx(inputs: &[usize]) -> u64 {
    inputs.into_par().flat_map(flat_map).sum()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("sum_flatmap");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/sum_map_filter.rs
================================================
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use orx_parallel::*;
use rand::prelude::*;
use rand_chacha::ChaCha8Rng;
use rayon::iter::IntoParallelIterator;
use std::hint::black_box;

const SEED: u64 = 5426;
const FIB_UPPER_BOUND: u32 = 201;

fn map(idx: &usize) -> u32 {
    let idx = *idx;
    fibonacci(&(idx as u32))
}

fn filter(output: &u32) -> bool {
    !output.is_multiple_of(3)
}

fn fibonacci(n: &u32) -> u32 {
    let mut a = 0;
    let mut b = 1;
    for _ in 0..*n {
        let c = a + b;
        a = b;
        b = c;
    }
    a
}

fn inputs(len: usize) -> Vec<usize> {
    let mut rng = ChaCha8Rng::seed_from_u64(SEED);
    (0..len)
        .map(|_| rng.random_range(0..FIB_UPPER_BOUND) as usize)
        .collect()
}

fn seq(inputs: &[usize]) -> u32 {
    inputs.iter().map(map).filter(filter).sum()
}

fn rayon(inputs: &[usize]) -> u32 {
    use rayon::iter::ParallelIterator;
    inputs.into_par_iter().map(map).filter(filter).sum()
}

fn orx(inputs: &[usize]) -> u32 {
    inputs.into_par().map(map).filter(filter).sum()
}

fn run(c: &mut Criterion) {
    let treatments = [65_536 * 2];

    let mut group = c.benchmark_group("sum_map_filter");

    for n in &treatments {
        let input = inputs(*n);
        let expected = seq(&input);

        group.bench_with_input(BenchmarkId::new("seq", n), n, |b, _| {
            assert_eq!(&expected, &seq(&input));
            b.iter(|| seq(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("rayon", n), n, |b, _| {
            assert_eq!(&expected, &rayon(&input));
            b.iter(|| rayon(black_box(&input)))
        });

        group.bench_with_input(BenchmarkId::new("orx", n), n, |b, _| {
            assert_eq!(&expected, &orx(&input));
            b.iter(|| orx(black_box(&input)))
        });
    }

    group.finish();
}

criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/t_par_merge_sorted.rs
================================================
use criterion::{Criterion, criterion_group, criterion_main};

#[cfg(feature = "experiment")]
mod inner {
    use criterion::Criterion;
    use orx_criterion::{Experiment, Factors};
    use orx_parallel::DefaultRunner;
    use orx_parallel::experiment::algorithms::merge_sorted_slices::par::{
        ParamsParMergeSortedSlices, PivotSearch, par_merge,
    };
    use orx_parallel::experiment::algorithms::merge_sorted_slices::seq::{
        ParamsSeqMergeSortedSlices, StreakSearch,
    };
    use orx_parallel::experiment::data_structures::slice_dst::SliceDst;
    use orx_parallel::experiment::data_structures::slice_src::SliceSrc;
    use rand::prelude::*;
    use rand_chacha::ChaCha8Rng;
    use std::cell::UnsafeCell;

    type X = usize;

    fn elem(i: usize) -> X {
        i
    }

    #[inline(always)]
    fn is_leq(a: &X, b: &X) -> bool {
        a < b
    }

    fn new_vec<T: Ord>(len: usize, elem: impl Fn(usize) -> T, sort_kind: SortKind) -> Vec<T> {
        let mut vec: Vec<_> = (0..len).map(elem).collect();
        match sort_kind {
            SortKind::Sorted => vec.sort(),
            SortKind::Mixed => {
                let num_shuffles = 10 * len;
                let mut rng = ChaCha8Rng::seed_from_u64(42);
                for _ in 0..num_shuffles {
                    let i = rng.random_range(0..len);
                    let j = rng.random_range(0..len);
                    vec.swap(i, j);
                }
            }
        }
        vec
    }

    fn split_to_sorted_vecs<T: Ord + Clone>(vec: &[T], split_kind: SplitKind) -> (Vec<T>, Vec<T>) {
        split_at(vec, split_kind.split_point(vec.len()))
    }

    fn split_at<T: Ord + Clone>(vec: &[T], split_at: usize) -> (Vec<T>, Vec<T>) {
        let (left, right) = vec.split_at(split_at);
        let mut left = left.to_vec();
        let mut right = right.to_vec();
        left.sort();
        right.sort();
        (left, right)
    }

    // treatments

    #[derive(Clone, Copy, Debug)]
    #[allow(dead_code)]
    enum SortKind {
        Sorted,
        Mixed,
    }

    #[derive(Clone, Copy, Debug)]
    #[allow(dead_code)]
    enum SplitKind {
        MoreInLeft,
        MoreInRight,
        Middle,
    }

    impl SplitKind {
        fn split_point(&self, len: usize) -> usize {
            match self {
                Self::MoreInLeft => len * 3 / 4,
                Self::MoreInRight => len / 4,
                Self::Middle => len / 2,
            }
        }
    }

    struct Input {
        left: Vec<X>,
        right: Vec<X>,
        target: UnsafeCell<Vec<X>>,
    }

    impl Drop for Input {
        fn drop(&mut self) {
            unsafe {
                let target = &mut *self.target.get();
                target.set_len(self.left.len() + self.right.len());
                self.left.set_len(0);
                self.right.set_len(0);
            }
        }
    }

    struct MergeData {
        e: usize,
        sort: SortKind,
        split: SplitKind,
    }

    impl Factors for MergeData {
        fn factor_names() -> Vec<&'static str> {
            vec!["e (len=2^e)", "sort", "split"]
        }

        fn factor_names_short() -> Vec<&'static str> {
            vec!["e", "so", "sp"]
        }

        fn factor_levels(&self) -> Vec<String> {
            vec![
                self.e.to_string(),
                format!("{:?}", self.sort),
                format!("{:?}", self.split),
            ]
        }

        fn factor_levels_short(&self) -> Vec<String> {
            vec![
                self.e.to_string(),
                match self.sort {
                    SortKind::Sorted => "T",
                    SortKind::Mixed => "F",
                }
                .to_string(),
                match self.split {
                    SplitKind::Middle => "M",
                    SplitKind::MoreInLeft => "L",
                    SplitKind::MoreInRight => "R",
                }
                .to_string(),
            ]
        }
    }

    impl MergeData {
        fn all() -> Vec<Self> {
            let mut all = vec![];

            let e = [15, 20];
            let sort = [SortKind::Mixed];
            let split = [SplitKind::Middle];

            for e in e {
                for sort in sort {
                    for split in split {
                        all.push(MergeData { e, sort, split });
                    }
                }
            }
            all
        }
    }

    // factors

    struct Params(ParamsParMergeSortedSlices);

    impl Factors for Params {
        fn factor_names() -> Vec<&'static str> {
            vec![
                "streak_search",
                "pivot_search",
                "put_large_to_left",
                "min_split_len",
                "chunk_size",
                "num_threads",
            ]
        }

        fn factor_names_short() -> Vec<&'static str> {
            vec!["ss", "ps", "ll", "min", "ch", "nt"]
        }

        fn factor_levels(&self) -> Vec<String> {
            vec![
                format!("{:?}", self.0.seq_params.streak_search),
                format!("{:?}", self.0.pivot_search),
                self.0.put_large_to_left.to_string(),
                self.0.min_split_len.to_string(),
                self.0.chunk_size.to_string(),
                self.0.num_threads.to_string(),
            ]
        }

        fn factor_levels_short(&self) -> Vec<String> {
            vec![
                match self.0.seq_params.streak_search {
                    StreakSearch::None => "X",
                    StreakSearch::Linear => "L",
                    StreakSearch::Binary => "B",
                }
                .to_string(),
                match self.0.pivot_search {
                    PivotSearch::Linear => "L",
                    PivotSearch::Binary => "B",
                }
                .to_string(),
                match self.0.put_large_to_left {
                    true => "T",
                    false => "F",
                }
                .to_string(),
                self.0.min_split_len.to_string(),
                self.0.chunk_size.to_string(),
                self.0.num_threads.to_string(),
            ]
        }
    }

    impl Params {
        fn all() -> Vec<Self> {
            let mut all = vec![];
            let put_large_to_left = [false, true];
            let min_split_len = [1024];
            let streak_search = [StreakSearch::None, StreakSearch::Linear];
            let pivot_search = [PivotSearch::Linear, PivotSearch::Binary];
            let chunk_size = [1, 1024];
            let num_threads = [1, 8];

            for put_large_to_left in put_large_to_left[..1].to_vec() {
                for min_split_len in min_split_len[..1].to_vec() {
                    for streak_search in streak_search[..1].to_vec() {
                        for pivot_search in pivot_search[..1].to_vec() {
                            for chunk_size in chunk_size[..1].to_vec() {
                                for num_threads in num_threads {
                                    all.push(Self(ParamsParMergeSortedSlices {
                                        seq_params: ParamsSeqMergeSortedSlices {
                                            streak_search,
                                            put_large_to_left,
                                        },
                                        put_large_to_left,
                                        min_split_len,
                                        pivot_search,
                                        num_threads,
                                        chunk_size,
                                    }));
                                }
                            }
                        }
                    }
                }
            }

            all
        }
    }

    // exp

    struct TuneExperiment;

    impl Experiment for TuneExperiment {
        type InputFactors = MergeData;

        type AlgFactors = Params;

        type Input = Input;

        type Output = ();

        fn input(&mut self, treatment: &Self::InputFactors) -> Self::Input {
            let len = 1 << treatment.e;
            let vec = new_vec(len, elem, treatment.sort);
            let (left, right) = split_to_sorted_vecs(&vec, treatment.split);
            let target = Vec::with_capacity(vec.len()).into();
            Input {
                left,
                right,
                target,
            }
        }

        fn execute(&mut self, variant: &Self::AlgFactors, input: &Self::Input) -> Self::Output {
            let target = unsafe { &mut *input.target.get() };
            let target = SliceDst::from_vec(target);
            let left = SliceSrc::from_slice(input.left.as_slice());
            let right = SliceSrc::from_slice(input.right.as_slice());
            let params = variant.0;
            par_merge(
                is_leq,
                left,
                right,
                target,
                &params,
                DefaultRunner::default(),
            );
        }
    }

    pub fn run(c: &mut Criterion) {
        let treatments = MergeData::all();
        let variants = Params::all();
        TuneExperiment.bench(c, "t_seq_merge_sorted", &treatments, &variants);
    }
}

#[cfg(feature = "experiment")]
fn run(c: &mut Criterion) {
    inner::run(c);
}
#[cfg(not(feature = "experiment"))]
fn run(_: &mut Criterion) {
    panic!("REQUIRES FEATURE: experiment");
}
criterion_group!(benches, run);
criterion_main!(benches);


================================================
FILE: benches/t_seq_merge_sorted.rs
================================================
use criterion::{Criterion, criterion_group, criterion_main};

#[cfg(feature = "experiment")]
mod inner {
    use criterion::Criterion;
    use orx_criterion::{Experiment, Factors};
    use orx_parallel::experiment::algorithms::merge_sorted_slices::seq::seq_merge;
    use orx_parallel::experiment::algorithms::merge_sorted_slices::seq::{
        ParamsSeqMergeSortedSlices, StreakSearch,
    };
    use orx_parallel::experiment::data_structures::slice_dst::SliceDst;
    use orx_parallel::experiment::data_structures::slice_src::SliceSrc;
    use rand::prelude::*;
    use rand_chacha::ChaCha8Rng;
    use std::cell::UnsafeCell;

    type X = usize;

    fn elem(i: usize) -> X {
        i
    }

    #[inline(always)]
    fn is_leq(a: &X, b: &X) -> bool {
        a < b
    }

    fn new_vec<T: Ord>(len: usize, elem: impl Fn(usize) -> T, sort_kind: SortKind) -> Vec<T> {
        let mut vec: Vec<_> = (0..len).map(elem).collect();
        match sort_kind {
            SortKind::Sorted => vec.sort(),
            SortKind::Mixed => {
                let num_shuffles = 10 * len;
                let mut rng = ChaCha8Rng::seed_from_u64(42);
                for _ in 0..num_shuffles {
                    let i = rng.random_range(0..len);
                    let j = rng.random_range(0..len);
                    vec.swap(i, j);
                }
            }
        }
        vec
    }

    fn split_to_sorted_vecs<T: Ord + Clone>(vec: &[T], split_kind: SplitKind) -> (Vec<T>, Vec<T>) {
        split_at(vec, split_kind.split_point(vec.len()))
    }

    fn split_at<T: Ord + Clone>(vec: &[T], split_at: usize) -> (Vec<T>, Vec<T>) {
        let (left, right) = vec.split_at(split_at);
        let mut left = left.to_vec();
        let mut right = right.to_vec();
        left.sort();
        right.sort();
        (left, right)
    }

    // treatments

    #[derive(Clone, Copy, Debug)]
    enum SortKind {
        Sorted,
        Mixed,
    }

    #[derive(Clone, Copy, Debug)]
    enum SplitKind {
        MoreInLeft,
        MoreInRight,
        Middle,
    }

    impl SplitKind {
        fn split_point(&self, len: usize) -> usize {
            match self {
                Self::MoreInLeft => len * 3 / 4,
                Self::MoreInRight => len / 4,
                Self::Middle => len / 2,
            }
        }
    }

    struct Input {
        left: Vec<X>,
        right: Vec<X>,
        target: UnsafeCell<Vec<X>>,
    }

    impl Drop for Input {
        fn drop(&mut self) {
            unsafe {
                let target = &mut *self.target.get();
                target.set_len(self.left.len() + self.right.len());
                self.left.set_len(0);
                self.right.set_len(0);
            }
        }
    }

    struct MergeData {
        e: usize,
        sort: SortKind,
        split: SplitKind,
    }

    impl Factors for MergeData {
        fn factor_names() -> Vec<&'static str> {
            vec!["e (len=2^e)", "sort", "split"]
        }

        fn factor_names_short() -> Vec<&'static str> {
            vec!["e", "so", "sp"]
        }

        fn factor_levels(&self) -> Vec<String> {
            vec![
                self.e.to_string(),
                format!("{:?}", self.sort),
                format!("{:?}", self.split),
            ]
        }

        fn factor_levels_short(&self) -> Vec<String> {
            vec![
                self.e.to_string(),
                match self.sort {
                    SortKind::Sorted => "T",
                    SortKind::Mixed => "F",
                }
           
Download .txt
gitextract_lozyb1bf/

├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .scripts/
│   ├── run_benchmark.sh
│   └── run_benchmarks.sh
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── benches/
│   ├── chain3_collect_map.rs
│   ├── chain4_collect_map.rs
│   ├── chain_collect_map.rs
│   ├── collect_filter.rs
│   ├── collect_filtermap.rs
│   ├── collect_flatmap.rs
│   ├── collect_iter_into_par.rs
│   ├── collect_long_chain.rs
│   ├── collect_map.rs
│   ├── collect_map_filter.rs
│   ├── collect_map_filter_hash_set.rs
│   ├── count_filtermap.rs
│   ├── count_flatmap.rs
│   ├── count_map.rs
│   ├── count_map_filter.rs
│   ├── drain_vec_collect_map_filter.rs
│   ├── find.rs
│   ├── find_any.rs
│   ├── find_flatmap.rs
│   ├── find_iter_into_par.rs
│   ├── find_map_filter.rs
│   ├── mut_for_each_iter.rs
│   ├── mut_for_each_slice.rs
│   ├── rec_iter_map_collect.rs
│   ├── rec_iter_map_sum.rs
│   ├── reduce.rs
│   ├── reduce_iter_into_par.rs
│   ├── reduce_long_chain.rs
│   ├── reduce_map.rs
│   ├── reduce_map_filter.rs
│   ├── result_collect_map.rs
│   ├── result_reduce_map.rs
│   ├── results/
│   │   └── benchmark-results.xlsx
│   ├── sum.rs
│   ├── sum_filtermap.rs
│   ├── sum_flatmap.rs
│   ├── sum_map_filter.rs
│   ├── t_par_merge_sorted.rs
│   ├── t_seq_merge_sorted.rs
│   ├── vec_deque_collect_map_filter.rs
│   └── vec_deque_collect_map_filter_owned.rs
├── docs/
│   └── using.md
├── examples/
│   ├── benchmark_collect.rs
│   ├── benchmark_find.rs
│   ├── benchmark_find_any.rs
│   ├── benchmark_heterogeneous.rs
│   ├── benchmark_pools.rs
│   ├── benchmark_reduce.rs
│   ├── collection_of_results.rs
│   ├── function_composition_with_mut_using.rs
│   ├── map_while.rs
│   ├── max_num_threads_config.rs
│   ├── mutable_par_iter.rs
│   ├── par_merge_sorted.rs
│   ├── parallelization_on_tree/
│   │   ├── collection_on_entire_tree.rs
│   │   ├── main.rs
│   │   ├── node.rs
│   │   ├── reduction_on_entire_tree.rs
│   │   ├── reduction_on_subset_of_tree.rs
│   │   ├── run_utils.rs
│   │   └── tree.rs
│   ├── using_for_each.rs
│   ├── using_map.rs
│   ├── using_metrics.rs
│   ├── using_random_walk.rs
│   └── utils/
│       ├── benchmark_utils.rs
│       └── mod.rs
├── src/
│   ├── collect_into/
│   │   ├── collect.rs
│   │   ├── fixed_vec.rs
│   │   ├── mod.rs
│   │   ├── par_collect_into.rs
│   │   ├── split_vec.rs
│   │   ├── utils.rs
│   │   └── vec.rs
│   ├── computational_variants/
│   │   ├── fallible_option.rs
│   │   ├── fallible_result/
│   │   │   ├── map_result.rs
│   │   │   ├── mod.rs
│   │   │   ├── par_result.rs
│   │   │   └── xap_result.rs
│   │   ├── map.rs
│   │   ├── mod.rs
│   │   ├── par.rs
│   │   ├── tests/
│   │   │   ├── copied.rs
│   │   │   ├── count.rs
│   │   │   ├── enumerate.rs
│   │   │   ├── fallible_option.rs
│   │   │   ├── fallible_result.rs
│   │   │   ├── flatten.rs
│   │   │   ├── for_each.rs
│   │   │   ├── inspect.rs
│   │   │   ├── iter_consuming.rs
│   │   │   ├── iter_ref.rs
│   │   │   ├── map/
│   │   │   │   ├── collect.rs
│   │   │   │   ├── find.rs
│   │   │   │   ├── mod.rs
│   │   │   │   └── reduce.rs
│   │   │   ├── min_max.rs
│   │   │   ├── mod.rs
│   │   │   ├── range.rs
│   │   │   ├── slice.rs
│   │   │   ├── sum.rs
│   │   │   ├── vectors.rs
│   │   │   └── xap/
│   │   │       ├── collect.rs
│   │   │       ├── find.rs
│   │   │       ├── mod.rs
│   │   │       └── reduce.rs
│   │   └── xap.rs
│   ├── default_fns.rs
│   ├── enumerate/
│   │   └── mod.rs
│   ├── env.rs
│   ├── executor/
│   │   ├── computation_kind.rs
│   │   ├── executor_with_diagnostics/
│   │   │   ├── mod.rs
│   │   │   ├── parallel_executor.rs
│   │   │   ├── shared_state.rs
│   │   │   └── thread_executor.rs
│   │   ├── fixed_chunk_executor/
│   │   │   ├── chunk_size.rs
│   │   │   ├── mod.rs
│   │   │   ├── parallel_executor.rs
│   │   │   └── thread_executor.rs
│   │   ├── mod.rs
│   │   ├── parallel_compute/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── next_any.rs
│   │   │   └── reduce.rs
│   │   ├── parallel_executor.rs
│   │   ├── thread_compute/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── next_any.rs
│   │   │   └── reduce.rs
│   │   └── thread_executor.rs
│   ├── experiment/
│   │   ├── algorithms/
│   │   │   ├── merge_sorted_slices/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── par.rs
│   │   │   │   ├── seq.rs
│   │   │   │   └── tests/
│   │   │   │       ├── inputs.rs
│   │   │   │       ├── mod.rs
│   │   │   │       ├── par.rs
│   │   │   │       └── seq.rs
│   │   │   └── mod.rs
│   │   ├── data_structures/
│   │   │   ├── mod.rs
│   │   │   ├── slice.rs
│   │   │   ├── slice_dst.rs
│   │   │   ├── slice_iter_ptr.rs
│   │   │   ├── slice_iter_ptr_dst.rs
│   │   │   ├── slice_iter_ptr_src.rs
│   │   │   ├── slice_src.rs
│   │   │   └── tests/
│   │   │       ├── mod.rs
│   │   │       └── slice.rs
│   │   └── mod.rs
│   ├── generic_iterator/
│   │   ├── collect.rs
│   │   ├── early_exit.rs
│   │   ├── iter.rs
│   │   ├── mod.rs
│   │   ├── reduce.rs
│   │   └── transformations.rs
│   ├── generic_values/
│   │   ├── fallible_iterators/
│   │   │   ├── mod.rs
│   │   │   └── result_of_iter.rs
│   │   ├── mod.rs
│   │   ├── option.rs
│   │   ├── option_result.rs
│   │   ├── result.rs
│   │   ├── runner_results/
│   │   │   ├── collect_arbitrary.rs
│   │   │   ├── collect_ordered.rs
│   │   │   ├── collect_sequential.rs
│   │   │   ├── fallibility.rs
│   │   │   ├── mod.rs
│   │   │   ├── next.rs
│   │   │   ├── reduce.rs
│   │   │   └── stop.rs
│   │   ├── transformable_values.rs
│   │   ├── values.rs
│   │   ├── vector.rs
│   │   ├── vector_result.rs
│   │   ├── whilst_atom.rs
│   │   ├── whilst_atom_result.rs
│   │   ├── whilst_iterators/
│   │   │   ├── mod.rs
│   │   │   ├── whilst_atom_flat_map.rs
│   │   │   └── whilst_option_flat_map.rs
│   │   ├── whilst_option.rs
│   │   ├── whilst_option_result.rs
│   │   ├── whilst_vector.rs
│   │   └── whilst_vector_result.rs
│   ├── heap_sort.rs
│   ├── into_par_iter.rs
│   ├── iter/
│   │   ├── mod.rs
│   │   ├── recursive/
│   │   │   ├── into_par_rec_iter.rs
│   │   │   ├── mod.rs
│   │   │   └── rec_par_iter.rs
│   │   └── special_iterators.rs
│   ├── iter_into_par_iter.rs
│   ├── lib.rs
│   ├── par_iter.rs
│   ├── par_iter_option.rs
│   ├── par_iter_result.rs
│   ├── par_thread_pool.rs
│   ├── parallel_drainable.rs
│   ├── parallelizable.rs
│   ├── parallelizable_collection.rs
│   ├── parallelizable_collection_mut.rs
│   ├── parameters/
│   │   ├── chunk_size.rs
│   │   ├── iteration_order.rs
│   │   ├── mod.rs
│   │   ├── num_threads.rs
│   │   └── params.rs
│   ├── runner/
│   │   ├── computation_kind.rs
│   │   ├── implementations/
│   │   │   ├── mod.rs
│   │   │   ├── pond.rs
│   │   │   ├── poolite.rs
│   │   │   ├── rayon_core.rs
│   │   │   ├── runner_with_pool.rs
│   │   │   ├── scoped_pool.rs
│   │   │   ├── scoped_threadpool.rs
│   │   │   ├── sequential.rs
│   │   │   ├── std_runner.rs
│   │   │   ├── tests/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── pond.rs
│   │   │   │   ├── poolite.rs
│   │   │   │   ├── rayon_core.rs
│   │   │   │   ├── scoped_pool.rs
│   │   │   │   ├── scoped_threadpool.rs
│   │   │   │   ├── sequential.rs
│   │   │   │   ├── std.rs
│   │   │   │   ├── utils.rs
│   │   │   │   └── yastl.rs
│   │   │   └── yastl.rs
│   │   ├── mod.rs
│   │   ├── num_spawned.rs
│   │   └── parallel_runner.rs
│   ├── special_type_sets/
│   │   ├── mod.rs
│   │   └── sum.rs
│   ├── test_utils.rs
│   ├── using/
│   │   ├── collect_into/
│   │   │   ├── collect.rs
│   │   │   ├── fixed_vec.rs
│   │   │   ├── mod.rs
│   │   │   ├── split_vec.rs
│   │   │   ├── u_par_collect_into.rs
│   │   │   └── vec.rs
│   │   ├── computational_variants/
│   │   │   ├── mod.rs
│   │   │   ├── tests/
│   │   │   │   ├── copied.rs
│   │   │   │   ├── count.rs
│   │   │   │   ├── fallible_option.rs
│   │   │   │   ├── fallible_result.rs
│   │   │   │   ├── flatten.rs
│   │   │   │   ├── for_each.rs
│   │   │   │   ├── inspect.rs
│   │   │   │   ├── iter_consuming.rs
│   │   │   │   ├── iter_ref.rs
│   │   │   │   ├── map/
│   │   │   │   │   ├── collect.rs
│   │   │   │   │   ├── find.rs
│   │   │   │   │   ├── mod.rs
│   │   │   │   │   └── reduce.rs
│   │   │   │   ├── min_max.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── range.rs
│   │   │   │   ├── slice.rs
│   │   │   │   ├── sum.rs
│   │   │   │   ├── utils.rs
│   │   │   │   ├── vectors.rs
│   │   │   │   └── xap/
│   │   │   │       ├── collect.rs
│   │   │   │       ├── find.rs
│   │   │   │       ├── mod.rs
│   │   │   │       └── reduce.rs
│   │   │   ├── u_fallible_option.rs
│   │   │   ├── u_fallible_result/
│   │   │   │   ├── mod.rs
│   │   │   │   ├── u_map_result.rs
│   │   │   │   ├── u_par_result.rs
│   │   │   │   └── u_xap_result.rs
│   │   │   ├── u_map.rs
│   │   │   ├── u_par.rs
│   │   │   └── u_xap.rs
│   │   ├── executor/
│   │   │   ├── mod.rs
│   │   │   ├── parallel_compute/
│   │   │   │   ├── collect_arbitrary.rs
│   │   │   │   ├── collect_ordered.rs
│   │   │   │   ├── mod.rs
│   │   │   │   ├── next.rs
│   │   │   │   ├── next_any.rs
│   │   │   │   └── reduce.rs
│   │   │   └── thread_compute/
│   │   │       ├── collect_arbitrary.rs
│   │   │       ├── collect_ordered.rs
│   │   │       ├── mod.rs
│   │   │       ├── next.rs
│   │   │       ├── next_any.rs
│   │   │       └── reduce.rs
│   │   ├── mod.rs
│   │   ├── u_par_iter.rs
│   │   ├── u_par_iter_option.rs
│   │   ├── u_par_iter_result.rs
│   │   └── using_variants.rs
│   └── value_variants/
│       ├── whilst_iterators/
│       │   ├── whilst_atom_flat_map.rs
│       │   └── whilst_option_flat_map.rs
│       └── whilst_vector.rs
└── tests/
    ├── chain.rs
    ├── into_par.rs
    ├── iter_into_par.rs
    ├── map_while_ok_collect/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   └── mod.rs
    ├── map_while_ok_collect_arbitrary/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   ├── mod.rs
    │   └── utils.rs
    ├── map_while_ok_reduce/
    │   ├── from_map.rs
    │   ├── from_par.rs
    │   ├── from_xap_chain.rs
    │   ├── from_xap_filter.rs
    │   ├── from_xap_filter_map.rs
    │   ├── from_xap_flat_map.rs
    │   └── mod.rs
    ├── mut_iter.rs
    ├── parallel_drainable.rs
    ├── parallelizable.rs
    ├── parallelizable_collection.rs
    ├── test_groups.rs
    ├── trait_bounds.rs
    ├── using/
    │   ├── mod.rs
    │   └── rng.rs
    └── whilst/
        ├── collect.rs
        ├── collect_arbitrary.rs
        ├── find.rs
        ├── mod.rs
        └── reduce.rs
Download .txt
SYMBOL INDEX (2306 symbols across 286 files)

FILE: benches/chain3_collect_map.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function fibonacci (line 45) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 56) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 63) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 67) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 77) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 86) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 95) | fn run(c: &mut Criterion) {

FILE: benches/chain4_collect_map.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function fibonacci (line 45) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 56) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 63) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 73) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 84) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 94) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 104) | fn run(c: &mut Criterion) {

FILE: benches/chain_collect_map.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function fibonacci (line 45) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 56) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 63) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 67) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 72) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 76) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 80) | fn run(c: &mut Criterion) {

FILE: benches/collect_filter.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function to_output (line 24) | fn to_output(idx: &usize) -> Output {
  function filter (line 45) | fn filter(output: &&Output) -> bool {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<Output> {
  function seq (line 70) | fn seq(inputs: &[Output]) -> Vec<&Output> {
  function rayon (line 74) | fn rayon(inputs: &[Output]) -> Vec<&Output> {
  function orx_into_vec (line 79) | fn orx_into_vec(inputs: &[Output]) -> Vec<&Output> {
  function orx_into_split_vec (line 83) | fn orx_into_split_vec(inputs: &[Output]) -> SplitVec<&Output> {
  function orx_into_vec_with (line 88) | fn orx_into_vec_with<P: ParThreadPool>(inputs: &[Output], pool: P) -> Ve...
  function run (line 92) | fn run(c: &mut Criterion) {

FILE: benches/collect_filtermap.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function filter_map (line 24) | fn filter_map(idx: &usize) -> Option<Output> {
  function to_output (line 28) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 49) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 60) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 67) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 71) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 76) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 80) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 84) | fn run(c: &mut Criterion) {

FILE: benches/collect_flatmap.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function flat_map (line 24) | fn flat_map(idx: &usize) -> Vec<Output> {
  function to_output (line 28) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 49) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 60) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 67) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 71) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 76) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_sorted_into_vec (line 80) | fn orx_sorted_into_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 84) | fn run(c: &mut Criterion) {

FILE: benches/collect_iter_into_par.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function filter (line 45) | fn filter(output: &Output) -> bool {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 69) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 73) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 78) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 87) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 96) | fn run(c: &mut Criterion) {

FILE: benches/collect_long_chain.rs
  constant SEED (line 9) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 10) | const FIB_UPPER_BOUND: u32 = 29;
  type Out1 (line 13) | struct Out1 {
  type Out2 (line 18) | struct Out2 {
  type Out3 (line 24) | struct Out3 {
  type Out4 (line 30) | struct Out4 {
  function map1 (line 36) | fn map1(idx: &usize) -> Out1 {
  function filter1 (line 48) | fn filter1(output: &Out1) -> bool {
  function map2 (line 54) | fn map2(input: Out1) -> Out2 {
  function filter2 (line 63) | fn filter2(output: &Out2) -> bool {
  function map3 (line 67) | fn map3(input: Out2) -> Out3 {
  function map4 (line 72) | fn map4(input: Out3) -> Out4 {
  function filter4 (line 79) | fn filter4(output: &Out4) -> bool {
  function fibonacci (line 83) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 94) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 101) | fn seq(inputs: &[usize]) -> Vec<Out4> {
  function rayon (line 114) | fn rayon(inputs: &[usize]) -> Vec<Out4> {
  function orx_into_vec (line 128) | fn orx_into_vec(inputs: &[usize]) -> Vec<Out4> {
  function orx_into_split_vec (line 141) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Out4> {
  function run (line 154) | fn run(c: &mut Criterion) {

FILE: benches/collect_map.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function fibonacci (line 45) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 56) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 63) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 67) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 72) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 76) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function run (line 80) | fn run(c: &mut Criterion) {

FILE: benches/collect_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function filter (line 45) | fn filter(output: &Output) -> bool {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 69) | fn seq(inputs: &[usize]) -> Vec<Output> {
  function rayon (line 73) | fn rayon(inputs: &[usize]) -> Vec<Output> {
  function orx_into_vec (line 78) | fn orx_into_vec(inputs: &[usize]) -> Vec<Output> {
  function orx_into_split_vec (line 82) | fn orx_into_split_vec(inputs: &[usize]) -> SplitVec<Output> {
  function orx_into_vec_with (line 87) | fn orx_into_vec_with<P: ParThreadPool>(inputs: &[usize], pool: P) -> Vec...
  function run (line 96) | fn run(c: &mut Criterion) {

FILE: benches/collect_map_filter_hash_set.rs
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 11) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 15) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 16) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 19) | struct Output {
  function map (line 24) | fn map(idx: &usize) -> Output {
  function filter (line 45) | fn filter(output: &Output) -> bool {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> HashSet<usize> {
  function seq (line 69) | fn seq(inputs: &HashSet<usize>) -> Vec<Output> {
  function rayon (line 73) | fn rayon(inputs: &HashSet<usize>) -> Vec<Output> {
  function orx_through_vec (line 78) | fn orx_through_vec(inputs: &HashSet<usize>) -> Vec<Output> {
  function orx_through_iter (line 83) | fn orx_through_iter(inputs: &HashSet<usize>) -> Vec<Output> {
  function run (line 92) | fn run(c: &mut Criterion) {

FILE: benches/count_filtermap.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function filter_map (line 23) | fn filter_map(idx: &usize) -> Option<Output> {
  function to_output (line 27) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 48) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 59) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 66) | fn seq(inputs: &[usize]) -> usize {
  function rayon (line 70) | fn rayon(inputs: &[usize]) -> usize {
  function orx (line 75) | fn orx(inputs: &[usize]) -> usize {
  function run (line 79) | fn run(c: &mut Criterion) {

FILE: benches/count_flatmap.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = true;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function flat_map (line 23) | fn flat_map(idx: &usize) -> Vec<Output> {
  function to_output (line 27) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 48) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 59) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 66) | fn seq(inputs: &[usize]) -> usize {
  function rayon (line 70) | fn rayon(inputs: &[usize]) -> usize {
  function orx (line 75) | fn orx(inputs: &[usize]) -> usize {
  function run (line 79) | fn run(c: &mut Criterion) {

FILE: benches/count_map.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: &usize) -> Output {
  function fibonacci (line 44) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 55) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 62) | fn seq(inputs: &[usize]) -> usize {
  function rayon (line 66) | fn rayon(inputs: &[usize]) -> usize {
  function orx (line 71) | fn orx(inputs: &[usize]) -> usize {
  function run (line 75) | fn run(c: &mut Criterion) {

FILE: benches/count_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = true;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: &usize) -> Output {
  function filter (line 44) | fn filter(output: &Output) -> bool {
  function fibonacci (line 50) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 61) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 68) | fn seq(inputs: &[usize]) -> usize {
  function rayon (line 72) | fn rayon(inputs: &[usize]) -> usize {
  function orx (line 77) | fn orx(inputs: &[usize]) -> usize {
  function run (line 81) | fn run(c: &mut Criterion) {

FILE: benches/drain_vec_collect_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: usize) -> Output {
  function filter (line 43) | fn filter(output: &Output) -> bool {
  function fibonacci (line 49) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 60) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 67) | fn seq(input: &mut Vec<usize>) -> Vec<Output> {
  function rayon (line 71) | fn rayon(input: &mut Vec<usize>) -> Vec<Output> {
  function orx_into_vec (line 79) | fn orx_into_vec(input: &mut Vec<usize>) -> Vec<Output> {
  function orx_into_split_vec (line 83) | fn orx_into_split_vec(input: &mut Vec<usize>) -> SplitVec<Output> {
  function run (line 87) | fn run(c: &mut Criterion) {

FILE: benches/find.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 24) | struct Output {
  function to_output (line 30) | fn to_output(idx: &usize) -> Output {
  function get_find (line 53) | fn get_find(n: usize) -> impl Fn(&Output) -> bool {
  function fibonacci (line 57) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 68) | fn inputs(len: usize) -> Vec<Output> {
  function seq (line 76) | fn seq(inputs: &[Output], find: impl Fn(&Output) -> bool) -> Option<&Out...
  function rayon (line 80) | fn rayon(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync...
  function orx (line 85) | fn orx(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) ...
  function run (line 89) | fn run(c: &mut Criterion) {

FILE: benches/find_any.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 24) | struct Output {
  function to_output (line 30) | fn to_output(idx: &usize) -> Output {
  function get_find (line 53) | fn get_find(n: usize) -> impl Fn(&Output) -> bool {
  function fibonacci (line 57) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 68) | fn inputs(len: usize) -> Vec<Output> {
  function seq (line 76) | fn seq(inputs: &[Output], find: impl Fn(&Output) -> bool) -> Option<&Out...
  function rayon (line 80) | fn rayon(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync...
  function orx (line 85) | fn orx(inputs: &[Output], find: impl Fn(&Output) -> bool + Send + Sync) ...
  function run (line 92) | fn run(c: &mut Criterion) {

FILE: benches/find_flatmap.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 24) | struct Output {
  function flat_map (line 30) | fn flat_map(idx: &usize) -> Vec<Output> {
  function to_output (line 34) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 57) | fn fibonacci(n: &u32) -> u32 {
  function get_find (line 68) | fn get_find(n: usize) -> impl Fn(&Output) -> bool {
  function inputs (line 72) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 79) | fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -...
  function rayon (line 83) | fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync)...
  function orx (line 88) | fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -...
  function run (line 92) | fn run(c: &mut Criterion) {

FILE: benches/find_iter_into_par.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 24) | struct Output {
  function map (line 30) | fn map(idx: &usize) -> Output {
  function get_find (line 53) | fn get_find(n: usize) -> impl Fn(&Output) -> bool {
  function filter (line 57) | fn filter(a: &Output) -> bool {
  function fibonacci (line 61) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 72) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 79) | fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool) -> Option<Outpu...
  function rayon (line 83) | fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync)...
  function orx (line 93) | fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -...
  function run (line 102) | fn run(c: &mut Criterion) {

FILE: benches/find_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 24) | struct Output {
  function map (line 30) | fn map(idx: &usize) -> Output {
  function get_find (line 53) | fn get_find(n: usize) -> impl Fn(&Output) -> bool {
  function filter (line 57) | fn filter(a: &Output) -> bool {
  function fibonacci (line 61) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 72) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 79) | fn seq(inputs: &[usize], find: impl Fn(&Output) -> bool) -> Option<Outpu...
  function rayon (line 83) | fn rayon(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync)...
  function orx (line 92) | fn orx(inputs: &[usize], find: impl Fn(&Output) -> bool + Send + Sync) -...
  function run (line 96) | fn run(c: &mut Criterion) {

FILE: benches/mut_for_each_iter.rs
  type Data (line 5) | struct Data {
  function to_output (line 10) | fn to_output(idx: usize) -> Data {
  function inputs (line 16) | fn inputs(len: usize) -> HashMap<usize, Data> {
  function fibonacci (line 20) | fn fibonacci(n: usize) -> usize {
  function filter (line 31) | fn filter(data: &&mut Data) -> bool {
  function update (line 35) | fn update(data: &mut Data) {
  function seq (line 42) | fn seq<'a>(inputs: impl Iterator<Item = &'a mut Data>) {
  function rayon (line 46) | fn rayon<'a>(inputs: impl Iterator<Item = &'a mut Data> + Send) {
  function orx (line 51) | fn orx<'a>(inputs: impl Iterator<Item = &'a mut Data>) {
  function run (line 56) | fn run(c: &mut Criterion) {

FILE: benches/mut_for_each_slice.rs
  type Data (line 5) | struct Data {
  function to_output (line 10) | fn to_output(idx: usize) -> Data {
  function inputs (line 16) | fn inputs(len: usize) -> Vec<Data> {
  function fibonacci (line 20) | fn fibonacci(n: usize) -> usize {
  function filter (line 31) | fn filter(data: &&mut Data) -> bool {
  function update (line 35) | fn update(data: &mut Data) {
  function seq (line 42) | fn seq(inputs: &mut [Data]) {
  function rayon (line 46) | fn rayon(inputs: &mut [Data]) {
  function orx (line 51) | fn orx(inputs: &mut [Data]) {
  function run (line 56) | fn run(c: &mut Criterion) {

FILE: benches/rec_iter_map_collect.rs
  function fibonacci (line 9) | fn fibonacci(n: u64, work: usize) -> u64 {
  type Node (line 25) | struct Node {
    method new (line 31) | fn new(mut n: u32, rng: &mut impl Rng) -> Self {
    method seq_num_nodes (line 52) | fn seq_num_nodes(&self) -> usize {
    method seq (line 60) | fn seq(&self, work: usize, numbers: &mut Vec<u64>) {
  function seq (line 70) | fn seq(roots: &[Node], work: usize) -> Vec<u64> {
  function orx_lazy_unknown_chunk1024 (line 78) | fn orx_lazy_unknown_chunk1024(roots: &[Node], work: usize) -> SplitVec<u...
  function orx_lazy_exact (line 90) | fn orx_lazy_exact(roots: &[Node], work: usize, num_nodes: usize) -> Spli...
  function orx_linearized (line 101) | fn orx_linearized(roots: &[Node], work: usize) -> SplitVec<u64> {
  function run (line 113) | fn run(c: &mut Criterion) {

FILE: benches/rec_iter_map_sum.rs
  function fibonacci (line 11) | fn fibonacci(n: u64, work: usize) -> u64 {
  type Node (line 27) | struct Node {
    method new (line 33) | fn new(mut n: u32, rng: &mut impl Rng) -> Self {
    method seq_num_nodes (line 54) | fn seq_num_nodes(&self) -> usize {
    method seq_sum_fib (line 62) | fn seq_sum_fib(&self, work: usize) -> u64 {
  function seq (line 74) | fn seq(roots: &[Node], work: usize) -> u64 {
  function rayon (line 78) | fn rayon(roots: &[Node], work: usize) -> u64 {
  function orx_lazy_unknown_chunk1024 (line 104) | fn orx_lazy_unknown_chunk1024(roots: &[Node], work: usize) -> u64 {
  function orx_lazy_exact (line 116) | fn orx_lazy_exact(roots: &[Node], work: usize, num_nodes: usize) -> u64 {
  function orx_lazy_exact_flat_map (line 127) | fn orx_lazy_exact_flat_map(roots: &[Node], work: usize, num_nodes: usize...
  function orx_linearized (line 138) | fn orx_linearized(roots: &[Node], work: usize) -> u64 {
  function run (line 150) | fn run(c: &mut Criterion) {

FILE: benches/reduce.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function to_output (line 23) | fn to_output(idx: &usize) -> Output {
  function reduce (line 44) | fn reduce<'a>(a: &'a Output, b: &'a Output) -> &'a Output {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<Output> {
  function seq (line 70) | fn seq(inputs: &[Output]) -> Option<&Output> {
  function rayon (line 74) | fn rayon(inputs: &[Output]) -> Option<&Output> {
  function orx (line 79) | fn orx(inputs: &[Output]) -> Option<&Output> {
  function run (line 83) | fn run(c: &mut Criterion) {

FILE: benches/reduce_iter_into_par.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: &usize) -> Output {
  function filter (line 44) | fn filter(a: &Output) -> bool {
  function reduce (line 48) | fn reduce(a: Output, b: Output) -> Output {
  function fibonacci (line 55) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 66) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 73) | fn seq(inputs: &[usize]) -> Option<Output> {
  function rayon (line 77) | fn rayon(inputs: &[usize]) -> Option<Output> {
  function orx (line 87) | fn orx(inputs: &[usize]) -> Option<Output> {
  function orx_with (line 97) | fn orx_with<P: ParThreadPool>(inputs: &[usize], pool: P) -> Option<Outpu...
  function run (line 107) | fn run(c: &mut Criterion) {

FILE: benches/reduce_long_chain.rs
  constant SEED (line 8) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 9) | const FIB_UPPER_BOUND: u32 = 29;
  type Out1 (line 12) | struct Out1 {
  type Out2 (line 17) | struct Out2 {
  type Out3 (line 23) | struct Out3 {
  type Out4 (line 29) | struct Out4 {
  function map1 (line 35) | fn map1(idx: &usize) -> Out1 {
  function filter1 (line 47) | fn filter1(output: &Out1) -> bool {
  function map2 (line 53) | fn map2(input: Out1) -> Out2 {
  function filter2 (line 62) | fn filter2(output: &Out2) -> bool {
  function map3 (line 66) | fn map3(input: Out2) -> Out3 {
  function map4 (line 71) | fn map4(input: Out3) -> Out4 {
  function filter4 (line 78) | fn filter4(output: &Out4) -> bool {
  function reduce (line 82) | fn reduce(x: Out4, y: Out4) -> Out4 {
  function fibonacci (line 95) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 106) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 113) | fn seq(inputs: &[usize]) -> Option<Out4> {
  function rayon (line 126) | fn rayon(inputs: &[usize]) -> Option<Out4> {
  function orx (line 140) | fn orx(inputs: &[usize]) -> Option<Out4> {
  function run (line 153) | fn run(c: &mut Criterion) {

FILE: benches/reduce_map.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: &usize) -> Output {
  function reduce (line 44) | fn reduce(a: Output, b: Output) -> Output {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 69) | fn seq(inputs: &[usize]) -> Option<Output> {
  function rayon (line 73) | fn rayon(inputs: &[usize]) -> Option<Output> {
  function orx (line 78) | fn orx(inputs: &[usize]) -> Option<Output> {
  function run (line 82) | fn run(c: &mut Criterion) {

FILE: benches/reduce_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function map (line 23) | fn map(idx: &usize) -> Output {
  function filter (line 44) | fn filter(a: &Output) -> bool {
  function reduce (line 48) | fn reduce(a: Output, b: Output) -> Output {
  function fibonacci (line 55) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 66) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 73) | fn seq(inputs: &[usize]) -> Option<Output> {
  function rayon (line 77) | fn rayon(inputs: &[usize]) -> Option<Output> {
  function orx (line 86) | fn orx(inputs: &[usize]) -> Option<Output> {
  function run (line 90) | fn run(c: &mut Criterion) {

FILE: benches/result_collect_map.rs
  type Err (line 7) | type Err = ParseIntError;
  constant TEST_LARGE_OUTPUT (line 9) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 10) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 11) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 12) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 13) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 14) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 16) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 20) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 21) | const FIB_UPPER_BOUND: u32 = 201;
  type Input (line 24) | struct Input {
  function to_input (line 30) | fn to_input(idx: &usize) -> Input {
  function to_bad_input (line 53) | fn to_bad_input() -> Input {
  function map_input_to_result (line 61) | fn map_input_to_result(input: &Input) -> Result<String, Err> {
  function fibonacci (line 68) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 79) | fn inputs(len: usize, idx_error: usize) -> Vec<Input> {
  function seq (line 92) | fn seq(inputs: &[Input], map: impl Fn(&Input) -> Result<String, Err>) ->...
  function rayon (line 96) | fn rayon(
  function orx (line 104) | fn orx(
  function orx_arbitrary (line 112) | fn orx_arbitrary(
  function run (line 125) | fn run(c: &mut Criterion) {

FILE: benches/result_reduce_map.rs
  type Err (line 8) | type Err = ParseIntError;
  constant TEST_LARGE_OUTPUT (line 10) | const TEST_LARGE_OUTPUT: bool = false;
  constant N (line 11) | const N: usize = 65_536 * 4;
  constant N_EARLY (line 12) | const N_EARLY: usize = 1000;
  constant N_MIDDLE (line 13) | const N_MIDDLE: usize = 65_536 * 2;
  constant N_LATE (line 14) | const N_LATE: usize = 65_536 * 4 - 10;
  constant N_NEVER (line 15) | const N_NEVER: usize = usize::MAX;
  constant LARGE_OUTPUT_LEN (line 17) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 21) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 22) | const FIB_UPPER_BOUND: u32 = 201;
  type Input (line 25) | struct Input {
  function to_input (line 31) | fn to_input(idx: &usize) -> Input {
  function to_bad_input (line 54) | fn to_bad_input() -> Input {
  function map_input_to_result (line 62) | fn map_input_to_result(input: &Input) -> Result<String, Err> {
  function map_to_number (line 69) | fn map_to_number(a: String) -> u32 {
  function fibonacci (line 74) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 85) | fn inputs(len: usize, idx_error: usize) -> Vec<Input> {
  function seq (line 98) | fn seq(inputs: &[Input], map: impl Fn(&Input) -> Result<String, Err>) ->...
  function rayon (line 118) | fn rayon(
  function orx (line 143) | fn orx(
  function orx_arbitrary (line 156) | fn orx_arbitrary(
  function run (line 170) | fn run(c: &mut Criterion) {

FILE: benches/sum.rs
  constant SEED (line 8) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 9) | const FIB_UPPER_BOUND: u32 = 201;
  function to_output (line 11) | fn to_output(idx: &usize) -> u32 {
  function fibonacci (line 16) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 27) | fn inputs(len: usize) -> Vec<u32> {
  function seq (line 35) | fn seq(inputs: &[u32]) -> u32 {
  function rayon (line 39) | fn rayon(inputs: &[u32]) -> u32 {
  function orx (line 44) | fn orx(inputs: &[u32]) -> u32 {
  function run (line 48) | fn run(c: &mut Criterion) {

FILE: benches/sum_filtermap.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function filter_map (line 23) | fn filter_map(idx: &usize) -> Option<u64> {
  function to_output (line 29) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 50) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 61) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 68) | fn seq(inputs: &[usize]) -> u64 {
  function rayon (line 72) | fn rayon(inputs: &[usize]) -> u64 {
  function orx (line 77) | fn orx(inputs: &[usize]) -> u64 {
  function run (line 81) | fn run(c: &mut Criterion) {

FILE: benches/sum_flatmap.rs
  constant TEST_LARGE_OUTPUT (line 8) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 10) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 14) | const SEED: u64 = 9562;
  constant FIB_UPPER_BOUND (line 15) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 18) | struct Output {
  function flat_map (line 23) | fn flat_map(idx: &usize) -> Vec<u64> {
  function to_output (line 30) | fn to_output(idx: &usize) -> Output {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 69) | fn seq(inputs: &[usize]) -> u64 {
  function rayon (line 73) | fn rayon(inputs: &[usize]) -> u64 {
  function orx (line 78) | fn orx(inputs: &[usize]) -> u64 {
  function run (line 82) | fn run(c: &mut Criterion) {

FILE: benches/sum_map_filter.rs
  constant SEED (line 8) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 9) | const FIB_UPPER_BOUND: u32 = 201;
  function map (line 11) | fn map(idx: &usize) -> u32 {
  function filter (line 16) | fn filter(output: &u32) -> bool {
  function fibonacci (line 20) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 31) | fn inputs(len: usize) -> Vec<usize> {
  function seq (line 38) | fn seq(inputs: &[usize]) -> u32 {
  function rayon (line 42) | fn rayon(inputs: &[usize]) -> u32 {
  function orx (line 47) | fn orx(inputs: &[usize]) -> u32 {
  function run (line 51) | fn run(c: &mut Criterion) {

FILE: benches/t_par_merge_sorted.rs
  type X (line 20) | type X = usize;
  function elem (line 22) | fn elem(i: usize) -> X {
  function is_leq (line 27) | fn is_leq(a: &X, b: &X) -> bool {
  function new_vec (line 31) | fn new_vec<T: Ord>(len: usize, elem: impl Fn(usize) -> T, sort_kind: Sor...
  function split_to_sorted_vecs (line 48) | fn split_to_sorted_vecs<T: Ord + Clone>(vec: &[T], split_kind: SplitKind...
  function split_at (line 52) | fn split_at<T: Ord + Clone>(vec: &[T], split_at: usize) -> (Vec<T>, Vec<...
  type SortKind (line 65) | enum SortKind {
  type SplitKind (line 72) | enum SplitKind {
    method split_point (line 79) | fn split_point(&self, len: usize) -> usize {
  type Input (line 88) | struct Input {
  method drop (line 95) | fn drop(&mut self) {
  type MergeData (line 105) | struct MergeData {
    method all (line 147) | fn all() -> Vec<Self> {
  method factor_names (line 112) | fn factor_names() -> Vec<&'static str> {
  method factor_names_short (line 116) | fn factor_names_short() -> Vec<&'static str> {
  method factor_levels (line 120) | fn factor_levels(&self) -> Vec<String> {
  method factor_levels_short (line 128) | fn factor_levels_short(&self) -> Vec<String> {
  type Params (line 167) | struct Params(ParamsParMergeSortedSlices);
    method all (line 222) | fn all() -> Vec<Self> {
  method factor_names (line 170) | fn factor_names() -> Vec<&'static str> {
  method factor_names_short (line 181) | fn factor_names_short() -> Vec<&'static str> {
  method factor_levels (line 185) | fn factor_levels(&self) -> Vec<String> {
  method factor_levels_short (line 196) | fn factor_levels_short(&self) -> Vec<String> {
  type TuneExperiment (line 261) | struct TuneExperiment;
  type InputFactors (line 264) | type InputFactors = MergeData;
  type AlgFactors (line 266) | type AlgFactors = Params;
  type Input (line 268) | type Input = Input;
  type Output (line 270) | type Output = ();
  method input (line 272) | fn input(&mut self, treatment: &Self::InputFactors) -> Self::Input {
  method execute (line 284) | fn execute(&mut self, variant: &Self::AlgFactors, input: &Self::Input) -...
  function run (line 301) | pub fn run(c: &mut Criterion) {
  function run (line 309) | fn run(c: &mut Criterion) {
  function run (line 313) | fn run(_: &mut Criterion) {

FILE: benches/t_seq_merge_sorted.rs
  type X (line 17) | type X = usize;
  function elem (line 19) | fn elem(i: usize) -> X {
  function is_leq (line 24) | fn is_leq(a: &X, b: &X) -> bool {
  function new_vec (line 28) | fn new_vec<T: Ord>(len: usize, elem: impl Fn(usize) -> T, sort_kind: Sor...
  function split_to_sorted_vecs (line 45) | fn split_to_sorted_vecs<T: Ord + Clone>(vec: &[T], split_kind: SplitKind...
  function split_at (line 49) | fn split_at<T: Ord + Clone>(vec: &[T], split_at: usize) -> (Vec<T>, Vec<...
  type SortKind (line 61) | enum SortKind {
  type SplitKind (line 67) | enum SplitKind {
    method split_point (line 74) | fn split_point(&self, len: usize) -> usize {
  type Input (line 83) | struct Input {
  method drop (line 90) | fn drop(&mut self) {
  type MergeData (line 100) | struct MergeData {
    method all (line 142) | fn all() -> Vec<Self> {
  method factor_names (line 107) | fn factor_names() -> Vec<&'static str> {
  method factor_names_short (line 111) | fn factor_names_short() -> Vec<&'static str> {
  method factor_levels (line 115) | fn factor_levels(&self) -> Vec<String> {
  method factor_levels_short (line 123) | fn factor_levels_short(&self) -> Vec<String> {
  type Params (line 166) | struct Params(ParamsSeqMergeSortedSlices);
    method all (line 202) | fn all() -> Vec<Self> {
  method factor_names (line 169) | fn factor_names() -> Vec<&'static str> {
  method factor_names_short (line 173) | fn factor_names_short() -> Vec<&'static str> {
  method factor_levels (line 177) | fn factor_levels(&self) -> Vec<String> {
  method factor_levels_short (line 184) | fn factor_levels_short(&self) -> Vec<String> {
  type TuneExperiment (line 224) | struct TuneExperiment;
  type InputFactors (line 227) | type InputFactors = MergeData;
  type AlgFactors (line 229) | type AlgFactors = Params;
  type Input (line 231) | type Input = Input;
  type Output (line 233) | type Output = ();
  method input (line 235) | fn input(&mut self, treatment: &Self::InputFactors) -> Self::Input {
  method execute (line 247) | fn execute(&mut self, variant: &Self::AlgFactors, input: &Self::Input) -...
  function run (line 257) | pub fn run(c: &mut Criterion) {
  function run (line 265) | fn run(c: &mut Criterion) {
  function run (line 269) | fn run(_: &mut Criterion) {

FILE: benches/vec_deque_collect_map_filter.rs
  constant TEST_LARGE_OUTPUT (line 10) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 12) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 16) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 17) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 20) | struct Output {
  function map (line 25) | fn map(idx: &usize) -> Output {
  function filter (line 46) | fn filter(output: &Output) -> bool {
  function fibonacci (line 52) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 63) | fn inputs(len: usize) -> VecDeque<usize> {
  function seq (line 70) | fn seq(inputs: &VecDeque<usize>) -> Vec<Output> {
  function rayon (line 74) | fn rayon(inputs: &VecDeque<usize>) -> Vec<Output> {
  function orx_into_vec (line 79) | fn orx_into_vec(inputs: &VecDeque<usize>) -> Vec<Output> {
  function orx_into_split_vec (line 83) | fn orx_into_split_vec(inputs: &VecDeque<usize>) -> SplitVec<Output> {
  function run (line 87) | fn run(c: &mut Criterion) {

FILE: benches/vec_deque_collect_map_filter_owned.rs
  constant TEST_LARGE_OUTPUT (line 10) | const TEST_LARGE_OUTPUT: bool = false;
  constant LARGE_OUTPUT_LEN (line 12) | const LARGE_OUTPUT_LEN: usize = match TEST_LARGE_OUTPUT {
  constant SEED (line 16) | const SEED: u64 = 5426;
  constant FIB_UPPER_BOUND (line 17) | const FIB_UPPER_BOUND: u32 = 201;
  type Output (line 20) | struct Output {
  function map (line 25) | fn map(idx: usize) -> Output {
  function filter (line 45) | fn filter(output: &Output) -> bool {
  function fibonacci (line 51) | fn fibonacci(n: &u32) -> u32 {
  function inputs (line 62) | fn inputs(len: usize) -> VecDeque<usize> {
  function seq (line 69) | fn seq(inputs: VecDeque<usize>) -> Vec<Output> {
  function rayon (line 73) | fn rayon(inputs: VecDeque<usize>) -> Vec<Output> {
  function orx_into_vec (line 78) | fn orx_into_vec(inputs: VecDeque<usize>) -> Vec<Output> {
  function orx_into_split_vec (line 82) | fn orx_into_split_vec(inputs: VecDeque<usize>) -> SplitVec<Output> {
  function run (line 86) | fn run(c: &mut Criterion) {

FILE: examples/benchmark_collect.rs
  function main (line 4) | fn main() {
  function main (line 26) | fn main() {

FILE: examples/benchmark_find.rs
  function main (line 4) | fn main() {
  function main (line 26) | fn main() {

FILE: examples/benchmark_find_any.rs
  function main (line 4) | fn main() {
  function main (line 26) | fn main() {

FILE: examples/benchmark_heterogeneous.rs
  function main (line 4) | fn main() {
  function main (line 26) | fn main() {

FILE: examples/benchmark_pools.rs
  function main (line 34) | fn main() {

FILE: examples/benchmark_reduce.rs
  function main (line 4) | fn main() {
  function main (line 26) | fn main() {

FILE: examples/collection_of_results.rs
  constant N (line 4) | const N: usize = 10_000;
  constant IDX_BAD_INPUT (line 5) | const IDX_BAD_INPUT: [usize; 4] = [1900, 4156, 6777, 5663];
  constant ITERATION_ORDERS (line 6) | const ITERATION_ORDERS: [IterationOrder; 2] = [IterationOrder::Ordered, ...
  function good_input (line 8) | fn good_input() -> Vec<String> {
  function bad_input (line 12) | fn bad_input() -> Vec<String> {
  function collection_of_results_good_case (line 22) | fn collection_of_results_good_case() {
  function collection_of_results_bad_case (line 50) | fn collection_of_results_bad_case() {
  function collect_result (line 93) | fn collect_result() {
  function main (line 115) | fn main() {

FILE: examples/function_composition_with_mut_using.rs
  function compose_mut_ref_unsafe_1 (line 44) | fn compose_mut_ref_unsafe_1<T, U, X, I, R>(
  function test_mut_ref_unsafe_1 (line 66) | fn test_mut_ref_unsafe_1() {
  function compose_mut_ref_unsafe_2 (line 88) | fn compose_mut_ref_unsafe_2<T, U, M, X, I, R>(
  function test_mut_ref_unsafe_2 (line 117) | fn test_mut_ref_unsafe_2() {
  function compose_unsafe_cell_on_reduce (line 144) | fn compose_unsafe_cell_on_reduce<T, U, M, X, I, R>(
  function test_unsafe_cell_on_reduce (line 173) | fn test_unsafe_cell_on_reduce() {
  function compose_unsafe_cell_on_all (line 200) | fn compose_unsafe_cell_on_all<T, U, M, X, I, R>(
  function test_unsafe_cell_on_all (line 231) | fn test_unsafe_cell_on_all() {
  function compose_clone (line 258) | fn compose_clone<T, U, X, I, R>(xap1: X, reduce1: R) -> impl FnOnce(&mut...
  function test_clone (line 273) | fn test_clone() {
  function compose_raw_ptr_all (line 295) | fn compose_raw_ptr_all<T, U, M, X, I, R>(
  function test_raw_ptr_all (line 320) | fn test_raw_ptr_all() {
  type Version (line 346) | enum Version {
  type Args (line 356) | struct Args {
  function main (line 362) | fn main() {

FILE: examples/map_while.rs
  constant N (line 3) | const N: usize = 10_000;
  constant IDX_BAD_INPUT (line 4) | const IDX_BAD_INPUT: [usize; 4] = [1900, 4156, 6777, 5663];
  function good_input (line 6) | fn good_input() -> Vec<String> {
  function bad_input (line 10) | fn bad_input() -> Vec<String> {
  function main (line 19) | fn main() {

FILE: examples/max_num_threads_config.rs
  function fib (line 13) | fn fib(n: &u64) -> u64 {
  constant MAX_NUM_THREADS_ENV_VARIABLE (line 26) | const MAX_NUM_THREADS_ENV_VARIABLE: &str = "ORX_PARALLEL_MAX_NUM_THREADS";
  function max_num_threads_by_env_variable (line 28) | fn max_num_threads_by_env_variable() -> Option<usize> {
  function main (line 39) | fn main() {

FILE: examples/mutable_par_iter.rs
  constant N (line 6) | const N: usize = 1_000_000;
  function mut_slice_into_par (line 8) | fn mut_slice_into_par() {
  function vec_par_mut (line 26) | fn vec_par_mut() {
  function iter_mut_into_par (line 43) | fn iter_mut_into_par() {
  function main (line 61) | fn main() {

FILE: examples/par_merge_sorted.rs
  function main (line 2) | fn main() {
  function main (line 7) | fn main() {

FILE: examples/parallelization_on_tree/collection_on_entire_tree.rs
  type Node (line 4) | type Node = crate::node::Node<String>;
  function run (line 6) | pub fn run(root: &Node) {
  function compute (line 41) | fn compute(node: &Node) -> u64 {
  function sequential (line 49) | fn sequential(root: &Node) -> Vec<u64> {
  function orx_rec (line 72) | fn orx_rec(root: &Node) -> Vec<u64> {
  function orx_rec_linearized (line 87) | fn orx_rec_linearized(root: &Node) -> Vec<u64> {
  function orx_rec_exact (line 110) | fn orx_rec_exact(root: &Node) -> Vec<u64> {

FILE: examples/parallelization_on_tree/main.rs
  type Args (line 15) | struct Args {
  function amount_of_work (line 21) | pub fn amount_of_work() -> &'static usize {
  function main (line 26) | fn main() {

FILE: examples/parallelization_on_tree/node.rs
  type Node (line 3) | pub struct Node<T> {
  method fmt (line 10) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  function num_nodes (line 28) | pub fn num_nodes(&self) -> usize {

FILE: examples/parallelization_on_tree/reduction_on_entire_tree.rs
  type Node (line 5) | type Node = crate::node::Node<String>;
  function run (line 7) | pub fn run(root: &Node) {
  function compute (line 57) | fn compute(node: &Node) -> u64 {
  function sequential (line 65) | fn sequential(root: &Node) -> u64 {
  function rayon (line 76) | pub fn rayon(root: &Node) -> u64 {
  function orx_rec (line 102) | fn orx_rec(root: &Node) -> u64 {
  function orx_rec_linearized (line 117) | fn orx_rec_linearized(root: &Node) -> u64 {
  function orx_rec_exact (line 136) | fn orx_rec_exact(root: &Node) -> u64 {

FILE: examples/parallelization_on_tree/reduction_on_subset_of_tree.rs
  type Node (line 4) | type Node = crate::node::Node<String>;
  function run (line 6) | pub fn run(root: &Node) {
  function compute (line 54) | fn compute(node: &Node) -> u64 {
  function filter (line 58) | fn filter(node: &&Node) -> bool {
  function sequential (line 66) | fn sequential(root: &Node) -> u64 {
  function push_orx_rec (line 85) | fn push_orx_rec(root: &Node) -> u64 {
  function collect_extend_orx_rec (line 102) | fn collect_extend_orx_rec(root: &Node) -> u64 {

FILE: examples/parallelization_on_tree/run_utils.rs
  function timed (line 4) | pub fn timed<F, L, T>(name: &'static str, fun: F, log: L)
  function compute (line 22) | pub fn compute(value: u64) -> u64 {

FILE: examples/parallelization_on_tree/tree.rs
  type Tree (line 5) | pub struct Tree<T>(PhantomData<T>);
  function new_node (line 8) | pub fn new_node(
  function create_node (line 51) | fn create_node<T>(out_edges: &[Vec<usize>], idx: usize, data: fn(usize) ...

FILE: examples/using_for_each.rs
  function for_each (line 6) | fn for_each() {
  function map (line 23) | fn map() {
  function main (line 43) | fn main() {

FILE: examples/using_map.rs
  constant N (line 6) | const N: u64 = 100_000;
  function fibonacci (line 9) | fn fibonacci(n: u64) -> u64 {
  function using (line 20) | fn using() -> u64 {
  function using_clone (line 32) | fn using_clone() -> u64 {
  function using_clone_while_counting_clones (line 46) | fn using_clone_while_counting_clones() -> u64 {
  function main (line 76) | fn main() {

FILE: examples/using_metrics.rs
  constant N (line 4) | const N: u64 = 10_000_000;
  constant MAX_NUM_THREADS (line 5) | const MAX_NUM_THREADS: usize = 8;
  function fibonacci (line 8) | fn fibonacci(n: u64) -> u64 {
  type ThreadMetrics (line 20) | struct ThreadMetrics {
  type ThreadMetricsWriter (line 27) | struct ThreadMetricsWriter<'a> {
  type ComputationMetrics (line 31) | struct ComputationMetrics {
    method new (line 35) | fn new() -> Self {
    method create_for_thread (line 49) | unsafe fn create_for_thread<'a>(&self, thread_idx: usize) -> ThreadMet...
  function main (line 68) | fn main() {

FILE: examples/using_random_walk.rs
  function random_walk (line 5) | fn random_walk(rng: &mut impl Rng, position: i64, num_steps: usize) -> i...
  function random_step (line 9) | fn random_step(rng: &mut impl Rng, position: i64) -> i64 {
  function input_positions (line 16) | fn input_positions() -> Vec<i64> {
  function sequential (line 20) | fn sequential() {
  function parallel (line 35) | fn parallel() {
  function main (line 50) | fn main() {

FILE: examples/utils/benchmark_utils.rs
  function timed_reduce (line 11) | fn timed_reduce<F, O>(num_repetitions: usize, expected_output: &Option<O...
  type Computation (line 38) | type Computation<'a, O> = (&'a str, Box<dyn Fn() -> O>);
  function timed_reduce_all (line 40) | pub fn timed_reduce_all<O>(
  function timed_collect (line 58) | fn timed_collect<F, Out, O>(num_repetitions: usize, expected_output: &[O...
  function timed_collect_all (line 81) | pub fn timed_collect_all<Out, O>(

FILE: src/collect_into/collect.rs
  function map_collect_into (line 11) | pub fn map_collect_into<R, I, O, M1, P>(
  function map_collect_into_seq (line 38) | fn map_collect_into_seq<I, O, M1, P>(iter: I, map1: M1, mut pinned_vec: ...
  function xap_collect_into (line 52) | pub fn xap_collect_into<R, I, Vo, X1, P>(
  function xap_collect_into_seq (line 95) | fn xap_collect_into_seq<I, Vo, X1, P>(iter: I, xap1: X1, mut pinned_vec:...
  function xap_try_collect_into (line 115) | pub fn xap_try_collect_into<R, I, Vo, X1, P>(
  function xap_try_collect_into_seq (line 151) | fn xap_try_collect_into_seq<I, Vo, X1, P>(

FILE: src/collect_into/fixed_vec.rs
  type BridgePinnedVec (line 16) | type BridgePinnedVec = Self;
  function empty (line 18) | fn empty(iter_len: Option<usize>) -> Self {
  function m_collect_into (line 23) | fn m_collect_into<R, I, M1>(self, orchestrator: R, params: Params, iter:...
  function x_collect_into (line 34) | fn x_collect_into<R, I, Vo, X1>(
  function x_try_collect_into (line 51) | fn x_try_collect_into<R, I, Vo, X1>(
  function length (line 72) | fn length(&self) -> usize {

FILE: src/collect_into/par_collect_into.rs
  type ParCollectIntoCore (line 10) | pub trait ParCollectIntoCore<O>: Collection<Item = O> {
    method empty (line 13) | fn empty(iter_len: Option<usize>) -> Self;
    method m_collect_into (line 15) | fn m_collect_into<R, I, M1>(self, orchestrator: R, params: Params, ite...
    method x_collect_into (line 21) | fn x_collect_into<R, I, Vo, X1>(
    method x_try_collect_into (line 34) | fn x_try_collect_into<R, I, Vo, X1>(
    method length (line 51) | fn length(&self) -> usize;
    method is_empty (line 54) | fn is_empty(&self) -> bool {
    method is_equal_to (line 59) | fn is_equal_to<'a>(&self, b: impl orx_iterable::Iterable<Item = &'a O>...
    method is_equal_to_ref (line 76) | fn is_equal_to_ref(&self, b: impl orx_iterable::Iterable<Item = O>) ->...
  type ParCollectInto (line 94) | pub trait ParCollectInto<O>: ParCollectIntoCore<O> + UParCollectIntoCore...

FILE: src/collect_into/split_vec.rs
  type BridgePinnedVec (line 19) | type BridgePinnedVec = Self;
  function empty (line 21) | fn empty(iter_len: Option<usize>) -> Self {
  function m_collect_into (line 27) | fn m_collect_into<R, I, M1>(
  function x_collect_into (line 45) | fn x_collect_into<R, I, Vo, X1>(
  function x_try_collect_into (line 63) | fn x_try_collect_into<R, I, Vo, X1>(
  function length (line 85) | fn length(&self) -> usize {

FILE: src/collect_into/utils.rs
  function extend_vec_from_split (line 5) | pub fn extend_vec_from_split<T, G>(
  function split_vec_reserve (line 22) | pub fn split_vec_reserve<T, G: GrowthWithConstantTimeAccess>(

FILE: src/collect_into/vec.rs
  type BridgePinnedVec (line 17) | type BridgePinnedVec = FixedVec<O>;
  function empty (line 19) | fn empty(iter_len: Option<usize>) -> Self {
  function m_collect_into (line 26) | fn m_collect_into<R, I, M1>(
  function x_collect_into (line 54) | fn x_collect_into<R, I, Vo, X1>(
  function x_try_collect_into (line 72) | fn x_try_collect_into<R, I, Vo, X1>(
  function length (line 94) | fn length(&self) -> usize {

FILE: src/computational_variants/fallible_option.rs
  type ParOption (line 10) | pub struct ParOption<F, T, R = DefaultRunner>
  function new (line 24) | pub(crate) fn new(par: F) -> Self {
  type Item (line 37) | type Item = T;
  function num_threads (line 41) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 45) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 49) | fn iteration_order(self, order: IterationOrder) -> Self {
  function with_runner (line 53) | fn with_runner<Q: ParallelRunner>(
  function map (line 62) | fn map<Out, Map>(self, map: Map) -> impl ParIterOption<R, Item = Out>
  function filter (line 70) | fn filter<Filter>(self, filter: Filter) -> impl ParIterOption<R, Item = ...
  function flat_map (line 79) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIterOptio...
  function filter_map (line 89) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl ParIt...
  function inspect (line 98) | fn inspect<Operation>(self, operation: Operation) -> impl ParIterOption<...
  function collect_into (line 109) | fn collect_into<C>(self, output: C) -> Option<C>
  function collect (line 117) | fn collect<C>(self) -> Option<C>
  function reduce (line 127) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Option<Self::Item>>
  function first (line 137) | fn first(self) -> Option<Option<Self::Item>>

FILE: src/computational_variants/fallible_result/map_result.rs
  type ParMapResult (line 11) | pub struct ParMapResult<I, T, E, O, M1, R = DefaultRunner>
  function new (line 29) | pub(crate) fn new(par: ParMap<I, O, M1, R>) -> Self {
  type Item (line 44) | type Item = T;
  type Err (line 46) | type Err = E;
  type RegularItem (line 48) | type RegularItem = O;
  type RegularParIter (line 50) | type RegularParIter = ParMap<I, O, M1, R>;
  function con_iter_len (line 52) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 56) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 60) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 69) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 82) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 95) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 108) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/computational_variants/fallible_result/par_result.rs
  type ParResult (line 11) | pub struct ParResult<I, T, E, R = DefaultRunner>
  function new (line 27) | pub(crate) fn new(par: Par<I, R>) -> Self {
  type Item (line 41) | type Item = T;
  type Err (line 43) | type Err = E;
  type RegularItem (line 45) | type RegularItem = I::Item;
  type RegularParIter (line 47) | type RegularParIter = Par<I, R>;
  function con_iter_len (line 49) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 53) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 57) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 66) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 79) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 92) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 105) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/computational_variants/fallible_result/xap_result.rs
  type ParXapResult (line 13) | pub struct ParXapResult<I, T, E, Vo, X1, R = DefaultRunner>
  function new (line 36) | pub(crate) fn new(orchestrator: R, params: Params, iter: I, xap1: X1) ->...
  function destruct (line 46) | fn destruct(self) -> (R, Params, I, X1) {
  type Item (line 59) | type Item = T;
  type Err (line 61) | type Err = E;
  type RegularItem (line 63) | type RegularItem = Vo::Item;
  type RegularParIter (line 65) | type RegularParIter = ParXap<I, Vo, X1, R>;
  function con_iter_len (line 67) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 71) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 76) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 83) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 93) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 106) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 119) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/computational_variants/map.rs
  type ParMap (line 13) | pub struct ParMap<I, O, M1, R = DefaultRunner>
  function new (line 31) | pub(crate) fn new(orchestrator: R, params: Params, iter: I, map1: M1) ->...
  function destruct (line 40) | pub(crate) fn destruct(self) -> (R, Params, I, M1) {
  type Item (line 67) | type Item = O;
  function con_iter (line 69) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 73) | fn params(&self) -> Params {
  function num_threads (line 79) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 84) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 89) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 94) | fn with_runner<Q: ParallelRunner>(self, orchestrator: Q) -> impl ParIter...
  function using (line 101) | fn using<'using, U, F>(
  function using_clone (line 115) | fn using_clone<U>(
  function map (line 130) | fn map<Out, Map>(self, map: Map) -> impl ParIter<R, Item = Out>
  function filter (line 139) | fn filter<Filter>(self, filter: Filter) -> impl ParIter<R, Item = Self::...
  function flat_map (line 152) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIter<R, I...
  function filter_map (line 162) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl ParIt...
  function take_while (line 171) | fn take_while<While>(self, take_while: While) -> impl ParIter<R, Item = ...
  function into_fallible_result (line 180) | fn into_fallible_result<Out, Err>(self) -> impl ParIterResult<R, Item = ...
  function collect_into (line 189) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 199) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 210) | fn first(self) -> Option<Self::Item>
  function enumerate (line 228) | fn enumerate(self) -> impl ParIter<R, Item = (usize, Self::Item)> {

FILE: src/computational_variants/par.rs
  type Par (line 16) | pub struct Par<I, R = DefaultRunner>
  function new (line 31) | pub(crate) fn new(orchestrator: R, params: Params, iter: I) -> Self {
  function destruct (line 39) | pub(crate) fn destruct(self) -> (R, Params, I) {
  function orchestrator (line 43) | pub(crate) fn orchestrator(&self) -> &R {
  type Item (line 67) | type Item = I::Item;
  function con_iter (line 69) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 73) | fn params(&self) -> Params {
  function num_threads (line 79) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 84) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 89) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 94) | fn with_runner<Q: ParallelRunner>(self, orchestrator: Q) -> impl ParIter...
  function using (line 100) | fn using<'using, U, F>(
  function using_clone (line 113) | fn using_clone<U>(
  function map (line 127) | fn map<Out, Map>(self, map: Map) -> impl ParIter<R, Item = Out>
  function filter (line 135) | fn filter<Filter>(self, filter: Filter) -> impl ParIter<R, Item = Self::...
  function flat_map (line 144) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIter<R, I...
  function filter_map (line 154) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl ParIt...
  function take_while (line 162) | fn take_while<While>(self, take_while: While) -> impl ParIter<R, Item = ...
  function into_fallible_result (line 171) | fn into_fallible_result<Out, Err>(self) -> impl ParIterResult<R, Item = ...
  function collect_into (line 180) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 190) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 201) | fn first(self) -> Option<Self::Item> {
  function chain (line 233) | pub fn chain<C>(self, other: C) -> Par<ChainKnownLenI<I, C::IntoIter>, R>
  function enumerate (line 249) | fn enumerate(self) -> impl ParIter<R, Item = (usize, Self::Item)> {

FILE: src/computational_variants/tests/copied.rs
  function input (line 5) | fn input<O: FromIterator<usize>>(n: usize) -> O {
  function copied_cloned_empty (line 10) | fn copied_cloned_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_map (line 26) | fn copied_cloned_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_xap_flat_map (line 43) | fn copied_cloned_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_xap_filter_map (line 60) | fn copied_cloned_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usiz...
  function copied_cloned_xap_filter_xap (line 77) | fn copied_cloned_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usiz...

FILE: src/computational_variants/tests/count.rs
  function input (line 7) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function count_empty (line 13) | fn count_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_map (line 25) | fn count_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_flat_map (line 38) | fn count_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_filter_map (line 52) | fn count_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_filter_xap (line 66) | fn count_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/enumerate.rs
  function enumerate_sequential (line 8) | fn enumerate_sequential(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function enumerate_map (line 22) | fn enumerate_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function enumerate_using (line 38) | fn enumerate_using(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/fallible_option.rs
  function input (line 7) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function fallible_option_collect_empty (line 13) | fn fallible_option_collect_empty(nt: &[usize], chunk: &[usize]) {
  function fallible_option_collect_partial_success (line 33) | fn fallible_option_collect_partial_success(n: &[usize], nt: &[usize], ch...
  function fallible_option_collect_complete_success (line 54) | fn fallible_option_collect_complete_success(n: &[usize], nt: &[usize], c...

FILE: src/computational_variants/tests/fallible_result.rs
  function input (line 7) | fn input<O: FromIterator<String>>(n: usize) -> O {
  type MyErr (line 13) | struct MyErr(String);
    method new (line 15) | fn new() -> Self {
  function fallible_result_collect_empty (line 21) | fn fallible_result_collect_empty(nt: &[usize], chunk: &[usize]) {
  function fallible_result_collect_partial_success (line 41) | fn fallible_result_collect_partial_success(n: &[usize], nt: &[usize], ch...
  function fallible_result_collect_complete_success (line 65) | fn fallible_result_collect_complete_success(n: &[usize], nt: &[usize], c...

FILE: src/computational_variants/tests/flatten.rs
  function flatten_empty (line 8) | fn flatten_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_map (line 27) | fn flatten_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_xap_filter_map (line 44) | fn flatten_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_xap_filter_xap (line 69) | fn flatten_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/for_each.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sorted (line 13) | fn sorted(mut x: Vec<String>) -> Vec<String> {
  function for_each_empty (line 19) | fn for_each_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_map (line 35) | fn for_each_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_flat_map (line 56) | fn for_each_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_filter_map (line 77) | fn for_each_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_filter_xap (line 98) | fn for_each_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/inspect.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sorted (line 13) | fn sorted(mut x: Vec<String>) -> Vec<String> {
  function inspect_empty (line 19) | fn inspect_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_map (line 36) | fn inspect_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_flat_map (line 58) | fn inspect_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_filter_map (line 80) | fn inspect_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_filter_xap (line 102) | fn inspect_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/iter_consuming.rs
  constant N_OFFSET (line 11) | const N_OFFSET: usize = 13;
  function offset (line 13) | fn offset() -> Vec<String> {
  function input (line 17) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 22) | fn expected(
  function empty_collect_into (line 44) | fn empty_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ...
  function empty_collect (line 65) | fn empty_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[u...
  function map_collect_into (line 88) | fn map_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ch...
  function map_collect (line 110) | fn map_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[usi...

FILE: src/computational_variants/tests/iter_ref.rs
  function input (line 11) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 16) | fn expected(input: &impl Collection<Item = String>, map: impl Fn(String)...
  function empty_collect_into (line 23) | fn empty_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function empty_collect (line 49) | fn empty_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect_into (line 77) | fn map_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect (line 94) | fn map_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/map/collect.rs
  constant N (line 12) | const N: [usize; 2] = [37, 125];
  constant N (line 14) | const N: [usize; 2] = [1025, 4735];
  function m_map_collect (line 22) | fn m_map_collect(n: usize, nt: usize, chunk: usize, ordering: IterationO...

FILE: src/computational_variants/tests/map/find.rs
  constant N (line 9) | const N: [usize; 2] = [37, 125];
  constant N (line 11) | const N: [usize; 2] = [1025, 4735];
  function m_find (line 18) | fn m_find(n: usize, nt: usize, chunk: usize) {
  function m_map_find (line 35) | fn m_map_find(n: usize, nt: usize, chunk: usize) {

FILE: src/computational_variants/tests/map/reduce.rs
  constant N (line 9) | const N: [usize; 2] = [37, 125];
  constant N (line 11) | const N: [usize; 2] = [1025, 4735];
  function m_reduce (line 18) | fn m_reduce(n: usize, nt: usize, chunk: usize) {
  function m_map_reduce (line 40) | fn m_map_reduce(n: usize, nt: usize, chunk: usize) {

FILE: src/computational_variants/tests/min_max.rs
  function input (line 7) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function cmp (line 12) | fn cmp(a: &usize, b: &usize) -> Ordering {
  function key (line 19) | fn key(a: &usize) -> u64 {
  function min_max_empty (line 24) | fn min_max_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_map (line 48) | fn min_max_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_flat_map (line 80) | fn min_max_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_filter_map (line 122) | fn min_max_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_filter_xap (line 169) | fn min_max_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/range.rs
  constant N_OFFSET (line 10) | const N_OFFSET: usize = 13;
  function offset (line 12) | fn offset() -> Vec<usize> {
  function expected (line 16) | fn expected<T>(
  function empty_collect_into (line 37) | fn empty_collect_into<C>(output: C, n: &[usize], nt: &[usize], chunk: &[...
  function empty_collect (line 55) | fn empty_collect<C>(_: C, n: &[usize], nt: &[usize], chunk: &[usize])
  function map_collect_into (line 75) | fn map_collect_into<C>(output: C, n: &[usize], nt: &[usize], chunk: &[us...
  function map_collect (line 94) | fn map_collect<C>(_: C, n: &[usize], nt: &[usize], chunk: &[usize])

FILE: src/computational_variants/tests/slice.rs
  function input (line 11) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 16) | fn expected(input: &impl Collection<Item = String>, map: impl Fn(String)...
  function empty_collect_into (line 23) | fn empty_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function empty_collect (line 49) | fn empty_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect_into (line 77) | fn map_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect (line 94) | fn map_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/sum.rs
  function input (line 6) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sum_empty (line 12) | fn sum_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_map (line 24) | fn sum_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_flat_map (line 38) | fn sum_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_filter_map (line 52) | fn sum_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_filter_xap (line 66) | fn sum_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/computational_variants/tests/vectors.rs
  constant N_OFFSET (line 11) | const N_OFFSET: usize = 13;
  function offset (line 13) | fn offset() -> Vec<String> {
  function input (line 17) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 22) | fn expected(
  function empty_collect_into (line 44) | fn empty_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ...
  function empty_collect (line 64) | fn empty_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[u...
  function map_collect_into (line 86) | fn map_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ch...
  function map_collect (line 107) | fn map_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[usi...

FILE: src/computational_variants/tests/xap/collect.rs
  constant N (line 15) | const N: [usize; 2] = [37, 125];
  constant N (line 17) | const N: [usize; 2] = [1025, 4735];
  function todo_panic_at_con_bag_new (line 20) | fn todo_panic_at_con_bag_new() {
  function x_flat_map_collect (line 65) | fn x_flat_map_collect(n: usize, nt: usize, chunk: usize, ordering: Itera...
  function x_filter_map_collect (line 104) | fn x_filter_map_collect(n: usize, nt: usize, chunk: usize, ordering: Ite...

FILE: src/computational_variants/tests/xap/find.rs
  constant N (line 13) | const N: [usize; 2] = [37, 125];
  constant N (line 15) | const N: [usize; 2] = [1025, 4735];
  function x_flat_map_find (line 22) | fn x_flat_map_find(n: usize, nt: usize, chunk: usize) {
  function x_filter_map_find (line 43) | fn x_filter_map_find(n: usize, nt: usize, chunk: usize) {

FILE: src/computational_variants/tests/xap/reduce.rs
  constant N (line 13) | const N: [usize; 2] = [37, 125];
  constant N (line 15) | const N: [usize; 2] = [1025, 4735];
  function x_flat_map_reduce (line 22) | fn x_flat_map_reduce(n: usize, nt: usize, chunk: usize) {
  function x_filter_map_reduce (line 47) | fn x_filter_map_reduce(n: usize, nt: usize, chunk: usize) {

FILE: src/computational_variants/xap.rs
  type ParXap (line 15) | pub struct ParXap<I, Vo, X1, R = DefaultRunner>
  function new (line 35) | pub(crate) fn new(orchestrator: R, params: Params, iter: I, xap1: X1) ->...
  function destruct (line 44) | pub(crate) fn destruct(self) -> (R, Params, I, X1) {
  type Item (line 74) | type Item = Vo::Item;
  function con_iter (line 76) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 80) | fn params(&self) -> Params {
  function num_threads (line 86) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 91) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 96) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 101) | fn with_runner<Q: ParallelRunner>(self, orchestrator: Q) -> impl ParIter...
  function using (line 108) | fn using<'using, U, F>(
  function using_clone (line 122) | fn using_clone<U>(
  function map (line 137) | fn map<Out, Map>(self, map: Map) -> impl ParIter<R, Item = Out>
  function filter (line 150) | fn filter<Filter>(self, filter: Filter) -> impl ParIter<R, Item = Self::...
  function flat_map (line 162) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIter<R, I...
  function filter_map (line 175) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl ParIt...
  function take_while (line 187) | fn take_while<While>(self, take_while: While) -> impl ParIter<R, Item = ...
  function into_fallible_result (line 199) | fn into_fallible_result<Out, Err>(self) -> impl ParIterResult<R, Item = ...
  function collect_into (line 209) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 219) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 231) | fn first(self) -> Option<Self::Item>

FILE: src/default_fns.rs
  function map_self (line 4) | pub fn map_self<T>(input: T) -> T {
  function map_count (line 9) | pub fn map_count<T>(_: T) -> usize {
  function map_copy (line 14) | pub fn map_copy<T: Copy>(x: &T) -> T {
  function map_clone (line 19) | pub fn map_clone<T: Clone>(x: &T) -> T {
  function reduce_sum (line 24) | pub fn reduce_sum<T>(a: T, b: T) -> T
  function reduce_unit (line 32) | pub fn reduce_unit(_: (), _: ()) {}
  function u_map_self (line 37) | pub fn u_map_self<U, T>(_: &mut U, input: T) -> T {
  function u_map_copy (line 42) | pub fn u_map_copy<U, T: Copy>(_: &mut U, x: &T) -> T {
  function u_map_clone (line 47) | pub fn u_map_clone<U, T: Clone>(_: &mut U, x: &T) -> T {
  function u_map_count (line 52) | pub fn u_map_count<U, T>(_: &mut U, _: T) -> usize {
  function u_reduce_sum (line 57) | pub fn u_reduce_sum<U, T>(_: &mut U, a: T, b: T) -> T
  function u_reduce_unit (line 65) | pub fn u_reduce_unit<U>(_: &mut U, _: (), _: ()) {}

FILE: src/enumerate/mod.rs
  type ParEnumerate (line 5) | pub trait ParEnumerate<R: ParallelRunner>: ParIter<R> {
    method enumerate (line 21) | fn enumerate(self) -> impl ParIter<R, Item = (usize, Self::Item)>;

FILE: src/env.rs
  constant MAX_NUM_THREADS_ENV_VARIABLE (line 4) | const MAX_NUM_THREADS_ENV_VARIABLE: &str = "ORX_PARALLEL_MAX_NUM_THREADS";
  function max_num_threads_by_env_variable (line 6) | pub fn max_num_threads_by_env_variable() -> Option<NonZeroUsize> {

FILE: src/executor/computation_kind.rs
  type ComputationKind (line 3) | pub enum ComputationKind {

FILE: src/executor/executor_with_diagnostics/parallel_executor.rs
  type ParallelExecutorWithDiagnostics (line 61) | pub struct ParallelExecutorWithDiagnostics<E>
  type SharedState (line 72) | type SharedState = SharedStateWithDiagnostics<E::SharedState>;
  type ThreadExecutor (line 74) | type ThreadExecutor = ThreadExecutorWithDiagnostics<E>;
  method new (line 76) | fn new(
  method new_shared_state (line 86) | fn new_shared_state(&self) -> Self::SharedState {
  method do_spawn_new (line 91) | fn do_spawn_new<I>(
  method new_thread_executor (line 104) | fn new_thread_executor(
  method complete_task (line 115) | fn complete_task(self, shared_state: Self::SharedState) {

FILE: src/executor/executor_with_diagnostics/shared_state.rs
  type SharedStateWithDiagnostics (line 5) | pub struct SharedStateWithDiagnostics<S> {
  function new (line 11) | pub fn new(inner: S) -> Self {
  function inner (line 20) | pub fn inner(&self) -> &S {
  function add_task_counts_of_thread (line 24) | pub fn add_task_counts_of_thread(&self, thread_idx: usize, chunk_sizes: ...
  function display (line 28) | pub fn display(self) {

FILE: src/executor/executor_with_diagnostics/thread_executor.rs
  type ThreadExecutorWithDiagnostics (line 7) | pub struct ThreadExecutorWithDiagnostics<E>
  function new (line 20) | pub(super) fn new(thread_idx: usize, executor: E::ThreadExecutor) -> Self {
  type SharedState (line 33) | type SharedState = SharedStateWithDiagnostics<E::SharedState>;
  method next_chunk_size (line 35) | fn next_chunk_size<I>(&self, shared_state: &Self::SharedState, iter: &I)...
  method begin_chunk (line 42) | fn begin_chunk(&mut self, chunk_size: usize) {
  method complete_chunk (line 46) | fn complete_chunk(&mut self, shared_state: &Self::SharedState, chunk_siz...
  method complete_task (line 52) | fn complete_task(&mut self, shared_state: &Self::SharedState) {

FILE: src/executor/fixed_chunk_executor/chunk_size.rs
  constant MAX_CHUNK_SIZE (line 4) | const MAX_CHUNK_SIZE: usize = 1 << 20;
  constant DESIRED_MIN_CHUNK_SIZE (line 5) | const DESIRED_MIN_CHUNK_SIZE: usize = 64;
  type ResolvedChunkSize (line 8) | pub enum ResolvedChunkSize {
    method new (line 14) | pub fn new(
    method chunk_size (line 27) | pub fn chunk_size(self) -> usize {
  function min_required_len (line 35) | const fn min_required_len(kind: ComputationKind, one_round_len: usize) -...
  function auto_chunk_size (line 43) | fn auto_chunk_size(
  function min_chunk_size (line 82) | fn min_chunk_size(
  function div_ceil (line 101) | const fn div_ceil(number: usize, divider: usize) -> usize {

FILE: src/executor/fixed_chunk_executor/parallel_executor.rs
  constant LAG_PERIODICITY (line 12) | const LAG_PERIODICITY: usize = 4;
  type FixedChunkRunner (line 14) | pub struct FixedChunkRunner {
    method spawn_new (line 33) | fn spawn_new(&self, num_spawned: usize, remaining: Option<usize>) -> b...
    method next_chunk (line 41) | fn next_chunk(&self, num_spawned: usize, remaining_len: Option<usize>)...
    method next_chunk_size_unknown_len (line 50) | fn next_chunk_size_unknown_len(&self, num_spawned: usize) -> Option<us...
    method next_chunk_size_known_len (line 57) | fn next_chunk_size_known_len(
  method clone (line 22) | fn clone(&self) -> Self {
  type SharedState (line 87) | type SharedState = ();
  type ThreadExecutor (line 89) | type ThreadExecutor = FixedChunkThreadExecutor;
  method new (line 91) | fn new(
  method new_shared_state (line 108) | fn new_shared_state(&self) -> Self::SharedState {}
  method do_spawn_new (line 110) | fn do_spawn_new<I>(&self, num_spawned: NumSpawned, _: &Self::SharedState...
  method new_thread_executor (line 125) | fn new_thread_executor(&self, _: usize, _: &Self::SharedState) -> Self::...
  method complete_task (line 131) | fn complete_task(self, _: Self::SharedState) {}

FILE: src/executor/fixed_chunk_executor/thread_executor.rs
  type FixedChunkThreadExecutor (line 4) | pub struct FixedChunkThreadExecutor {
  type SharedState (line 9) | type SharedState = ();
  method next_chunk_size (line 12) | fn next_chunk_size<I>(&self, _: &Self::SharedState, _: &I) -> usize
  method begin_chunk (line 19) | fn begin_chunk(&mut self, _: usize) {}
  method complete_chunk (line 21) | fn complete_chunk(&mut self, _: &Self::SharedState, _: usize) {}
  method complete_task (line 23) | fn complete_task(&mut self, _: &Self::SharedState) {}

FILE: src/executor/mod.rs
  type DefaultExecutor (line 15) | pub type DefaultExecutor = fixed_chunk_executor::FixedChunkRunner;

FILE: src/executor/parallel_compute/collect_arbitrary.rs
  function m (line 11) | pub fn m<C, I, O, M1, P>(
  function x (line 42) | pub fn x<C, I, Vo, X1, P>(

FILE: src/executor/parallel_compute/collect_ordered.rs
  function m (line 10) | pub fn m<C, I, O, M1, P>(
  function x (line 36) | pub fn x<C, I, Vo, X1, P>(

FILE: src/executor/parallel_compute/next.rs
  function m (line 8) | pub fn m<C, I, O, M1>(
  type ResultNext (line 36) | type ResultNext<Vo> = Result<
  function x (line 41) | pub fn x<C, I, Vo, X1>(

FILE: src/executor/parallel_compute/next_any.rs
  function m (line 8) | pub fn m<C, I, O, M1>(
  type ResultNextAny (line 32) | type ResultNextAny<Vo> =
  function x (line 35) | pub fn x<C, I, Vo, X1>(

FILE: src/executor/parallel_compute/reduce.rs
  function m (line 8) | pub fn m<C, I, O, M1, Red>(
  type ResultReduce (line 35) | type ResultReduce<Vo> =
  function x (line 38) | pub fn x<C, I, Vo, X1, Red>(

FILE: src/executor/parallel_executor.rs
  type ParallelExecutor (line 12) | pub trait ParallelExecutor: Sized + Sync + 'static + Clone {
    method new (line 21) | fn new(
    method new_shared_state (line 29) | fn new_shared_state(&self) -> Self::SharedState;
    method do_spawn_new (line 35) | fn do_spawn_new<I>(
    method new_thread_executor (line 46) | fn new_thread_executor(
    method complete_task (line 53) | fn complete_task(self, shared_state: Self::SharedState);

FILE: src/executor/thread_compute/collect_arbitrary.rs
  function m (line 11) | pub fn m<C, I, O, M1, P>(
  function x (line 65) | pub fn x<C, I, Vo, X1, P>(

FILE: src/executor/thread_compute/collect_ordered.rs
  function m (line 9) | pub fn m<C, I, O, M1, P>(
  function x (line 64) | pub fn x<C, I, Vo, X1>(

FILE: src/executor/thread_compute/next.rs
  function m (line 8) | pub fn m<C, I, O, M1>(
  function x (line 73) | pub fn x<C, I, Vo, X1>(

FILE: src/executor/thread_compute/next_any.rs
  function m (line 8) | pub fn m<C, I, O, M1>(
  function x (line 74) | pub fn x<C, I, Vo, X1>(

FILE: src/executor/thread_compute/reduce.rs
  function m (line 12) | pub fn m<C, I, O, M1, Red>(
  function x (line 84) | pub fn x<C, I, Vo, X1, Red>(

FILE: src/executor/thread_executor.rs
  type ThreadExecutor (line 5) | pub trait ThreadExecutor: Sized {
    method next_chunk_size (line 11) | fn next_chunk_size<I>(&self, shared_state: &Self::SharedState, iter: &...
    method begin_chunk (line 16) | fn begin_chunk(&mut self, chunk_size: usize);
    method complete_chunk (line 21) | fn complete_chunk(&mut self, shared_state: &Self::SharedState, chunk_s...
    method complete_task (line 26) | fn complete_task(&mut self, shared_state: &Self::SharedState);

FILE: src/experiment/algorithms/merge_sorted_slices/par.rs
  type PivotSearch (line 11) | pub enum PivotSearch {
  type ParamsParMergeSortedSlices (line 20) | pub struct ParamsParMergeSortedSlices {
  type Task (line 36) | struct Task<'a, T> {
  function clone (line 54) | unsafe fn clone(&self) -> Self {
  function par_merge (line 67) | pub fn par_merge<'a, T, F, R: ParallelRunner>(
  function handle_extend (line 106) | unsafe fn handle_extend<'a, T, F>(

FILE: src/experiment/algorithms/merge_sorted_slices/seq.rs
  function bin_search_idx (line 4) | pub(super) fn bin_search_idx(idx: Result<usize, usize>) -> usize {
  type StreakSearch (line 23) | pub enum StreakSearch {
  type ParamsSeqMergeSortedSlices (line 34) | pub struct ParamsSeqMergeSortedSlices {
  function seq_merge (line 46) | pub fn seq_merge<'a, T: 'a, F>(
  function seq_merge_unchecked (line 68) | pub unsafe fn seq_merge_unchecked<'a, T: 'a, F>(
  function seq_merge_streak_none (line 97) | unsafe fn seq_merge_streak_none<'a, T: 'a, F>(
  function seq_merge_streak_linear (line 163) | unsafe fn seq_merge_streak_linear<'a, T: 'a, F>(
  function seq_merge_streak_binary (line 237) | unsafe fn seq_merge_streak_binary<'a, T: 'a, F>(

FILE: src/experiment/algorithms/merge_sorted_slices/tests/inputs.rs
  type SortKind (line 7) | pub enum SortKind {
  function sorted_slices (line 13) | pub fn sorted_slices(

FILE: src/experiment/algorithms/merge_sorted_slices/tests/par.rs
  function runner (line 15) | fn runner() -> RunnerWithPool<DefaultPool> {
  constant PARAMS (line 19) | const PARAMS: &[ParamsSeqMergeSortedSlices] = &[
  function merge_sorted_slices_par (line 53) | fn merge_sorted_slices_par(
  function merge_sorted_slices_par_single_thread (line 75) | fn merge_sorted_slices_par_single_thread((left_len, total_len): (usize, ...
  function merge_sorted_slices_par_large (line 94) | fn merge_sorted_slices_par_large(len: usize, num_threads: usize, chunk_s...
  function run (line 110) | fn run((left_len, total_len): (usize, usize), sort: SortKind, params: Pa...

FILE: src/experiment/algorithms/merge_sorted_slices/tests/seq.rs
  constant PARAMS (line 11) | const PARAMS: &[ParamsSeqMergeSortedSlices] = &[
  function merge_sorted_slices_seq (line 43) | fn merge_sorted_slices_seq(

FILE: src/experiment/data_structures/slice.rs
  type Slice (line 4) | pub struct Slice<'a, T: 'a> {
  method clone (line 10) | fn clone(&self) -> Self {
  function from (line 19) | fn from(value: &[T]) -> Self {
  function new (line 27) | pub fn new(data: *const T, len: usize) -> Self {
  function destruct (line 35) | pub fn destruct(self) -> *const [T] {
  function split_at_unchecked (line 47) | pub unsafe fn split_at_unchecked(self, position: usize) -> [Self; 2] {
  function data (line 58) | pub(super) fn data(&self) -> *const T {
  function len (line 64) | pub fn len(&self) -> usize {
  function is_empty (line 69) | pub fn is_empty(&self) -> bool {
  function first_unchecked (line 80) | pub unsafe fn first_unchecked(&self) -> &'a T {
  function copy_from_nonoverlapping (line 88) | pub unsafe fn copy_from_nonoverlapping(&self, src: &Self) {
  function as_slice (line 100) | pub unsafe fn as_slice(&self) -> &'a [T] {
  type SliceSafe (line 107) | pub struct SliceSafe<'c, 'a, T: 'a>(&'c Slice<'a, T>);
  function new (line 111) | pub fn new(slice: &'c Slice<'a, T>) -> Self {
  function from (line 117) | fn from(value: &'c Slice<'a, T>) -> Self {
  function is_non_overlapping (line 124) | pub fn is_non_overlapping(&self, other: &Self) -> bool {

FILE: src/experiment/data_structures/slice_dst.rs
  type SliceDst (line 14) | pub struct SliceDst<'a, T>(Slice<'a, T>);
  function destruct (line 19) | pub fn destruct(self) -> *const [T] {
  function clone (line 32) | pub unsafe fn clone(&self) -> Self {
  function new (line 41) | pub unsafe fn new(data: *const T, len: usize) -> Self {
  function from_vec (line 54) | pub fn from_vec(vec: &'a mut Vec<T>) -> Self {
  function len (line 64) | pub fn len(&self) -> usize {
  function core (line 70) | pub fn core(&self) -> SliceSafe<'_, 'a, T> {
  function into_ptr_iter (line 75) | pub fn into_ptr_iter(self) -> SliceIterPtrDst<'a, T> {
  function split_at_unchecked (line 87) | pub unsafe fn split_at_unchecked(self, position: usize) -> [Self; 2] {
  function from (line 94) | fn from(value: &'c SliceDst<'a, T>) -> Self {

FILE: src/experiment/data_structures/slice_iter_ptr.rs
  type SliceIterPtr (line 4) | pub struct SliceIterPtr<'a, T: 'a> {
  method default (line 11) | fn default() -> Self {
  function new (line 26) | pub unsafe fn new(ptr: *const T, n: usize) -> Self {
  function is_finished (line 37) | pub fn is_finished(&self) -> bool {
  function remaining (line 44) | fn remaining(&self) -> usize {
  function peek (line 52) | pub fn peek(&self) -> *const T {
  function current (line 66) | pub unsafe fn current(&self) -> Option<&'a T> {
  function current_unchecked (line 83) | pub unsafe fn current_unchecked(&self) -> &'a T {
  function next_unchecked (line 98) | pub unsafe fn next_unchecked(&mut self) -> *const T {
  function next_n_unchecked (line 111) | pub unsafe fn next_n_unchecked(&mut self, count: usize) -> *const T {
  function jump_to_end (line 120) | pub fn jump_to_end(&mut self) {
  type Item (line 126) | type Item = *const T;
  method next (line 129) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 137) | fn size_hint(&self) -> (usize, Option<usize>) {
  method len (line 144) | fn len(&self) -> usize {

FILE: src/experiment/data_structures/slice_iter_ptr_dst.rs
  type SliceIterPtrDst (line 8) | pub struct SliceIterPtrDst<'a, T: 'a>(SliceIterPtr<'a, T>);
  method default (line 11) | fn default() -> Self {
  function new (line 21) | pub fn new(slice: SliceDst<'a, T>) -> Self {
  function is_finished (line 29) | pub fn is_finished(&self) -> bool {
  function len (line 36) | pub fn len(&self) -> usize {
  function write_one_from (line 50) | pub unsafe fn write_one_from(&mut self, src: &mut SliceIterPtrSrc<'a, T>) {
  function write_many_from (line 73) | pub unsafe fn write_many_from(&mut self, src: &mut SliceIterPtrSrc<'a, T...
  function write_rest_from (line 95) | pub unsafe fn write_rest_from(&mut self, src: &mut SliceIterPtrSrc<'a, T...

FILE: src/experiment/data_structures/slice_iter_ptr_src.rs
  type SliceIterPtrSrc (line 11) | pub struct SliceIterPtrSrc<'a, T: 'a>(SliceIterPtr<'a, T>);
  method default (line 14) | fn default() -> Self {
  function new (line 24) | pub fn new(slice: SliceSrc<'a, T>) -> Self {
  function is_finished (line 32) | pub fn is_finished(&self) -> bool {
  function current (line 39) | pub fn current(&self) -> Option<&'a T> {
  function next_unchecked (line 52) | pub unsafe fn next_unchecked(&mut self) -> *const T {
  function next_n_unchecked (line 63) | pub unsafe fn next_n_unchecked(&mut self, count: usize) -> *const T {
  function jump_to_end (line 69) | pub(super) fn jump_to_end(&mut self) {
  function values (line 75) | pub fn values(&self) -> core::slice::Iter<'a, T> {
  function as_slice (line 81) | pub fn as_slice(&self) -> &'a [T] {
  type Item (line 90) | type Item = *const T;
  method next (line 95) | fn next(&mut self) -> Option<Self::Item> {
  method size_hint (line 100) | fn size_hint(&self) -> (usize, Option<usize>) {
  method len (line 108) | fn len(&self) -> usize {

FILE: src/experiment/data_structures/slice_src.rs
  type SliceSrc (line 15) | pub struct SliceSrc<'a, T>(Slice<'a, T>);
  method clone (line 18) | fn clone(&self) -> Self {
  function destruct (line 26) | pub fn destruct(self) -> *const [T] {
  function from_slice (line 37) | pub fn from_slice(slice: &'a [T]) -> Self {
  function len (line 44) | pub fn len(&self) -> usize {
  function core (line 50) | pub fn core(&self) -> SliceSafe<'_, 'a, T> {
  function first_unchecked (line 60) | pub unsafe fn first_unchecked(&self) -> &'a T {
  function into_ptr_iter (line 67) | pub fn into_ptr_iter(self) -> SliceIterPtrSrc<'a, T> {
  function split_at_unchecked (line 79) | pub unsafe fn split_at_unchecked(self, position: usize) -> [Self; 2] {
  function as_slice (line 85) | pub fn as_slice(&self) -> &[T] {
  function values (line 92) | pub fn values(&'a self) -> core::slice::Iter<'a, T> {
  function from (line 98) | fn from(value: &'c SliceSrc<'a, T>) -> Self {

FILE: src/experiment/data_structures/tests/slice.rs
  function slice_overlap (line 7) | fn slice_overlap() {
  function slice_split_unchecked (line 36) | fn slice_split_unchecked(len: usize) {
  function slice_first_unchecked (line 54) | fn slice_first_unchecked(len: usize) {

FILE: src/generic_iterator/collect.rs
  function collect_vec (line 17) | pub fn collect_vec(self) -> Vec<T> {

FILE: src/generic_iterator/early_exit.rs
  function find (line 16) | pub fn find<Predicate>(self, predicate: Predicate) -> Option<T>
  function find_any (line 32) | pub fn find_any<Predicate>(self, predicate: Predicate) -> Option<T>

FILE: src/generic_iterator/iter.rs
  type GenericIterator (line 11) | pub enum GenericIterator<T, S, R, O>
  function sequential (line 32) | pub fn sequential(iter: S) -> Self {
  function rayon (line 43) | pub fn rayon(iter: R) -> Self {
  function orx (line 54) | pub fn orx(iter: O) -> Self {

FILE: src/generic_iterator/reduce.rs
  function reduce (line 17) | pub fn reduce<Reduce>(self, reduce: Reduce) -> Option<T>
  function count (line 33) | pub fn count(self) -> usize {
  function for_each (line 46) | pub fn for_each<Operation>(self, operation: Operation)
  function max (line 62) | pub fn max(self) -> Option<T>
  function max_by (line 78) | pub fn max_by<Compare>(self, compare: Compare) -> Option<T>
  function max_by_key (line 94) | pub fn max_by_key<Key, GetKey>(self, key: GetKey) -> Option<T>
  function min (line 111) | pub fn min(self) -> Option<T>
  function min_by (line 127) | pub fn min_by<Compare>(self, compare: Compare) -> Option<T>
  function min_by_key (line 143) | pub fn min_by_key<Key, GetKey>(self, key: GetKey) -> Option<T>
  function sum (line 160) | pub fn sum(self) -> T

FILE: src/generic_iterator/transformations.rs
  function map (line 18) | pub fn map<Out, Map>(
  function filter (line 43) | pub fn filter<Filter>(
  function flat_map (line 67) | pub fn flat_map<IOut, FlatMap>(
  function filter_map (line 97) | pub fn filter_map<Out, FilterMap>(
  function inspect (line 122) | pub fn inspect<Operation>(
  function flatten (line 148) | pub fn flatten(
  function copied (line 185) | pub fn copied(
  function cloned (line 208) | pub fn cloned(

FILE: src/generic_values/fallible_iterators/result_of_iter.rs
  type ResultOfIter (line 1) | pub struct ResultOfIter<I, E>
  function ok (line 13) | pub fn ok(iter: I) -> Self {
  function err (line 20) | pub fn err(error: E) -> Self {
  type Item (line 32) | type Item = Result<I::Item, E>;
  method next (line 35) | fn next(&mut self) -> Option<Self::Item> {

FILE: src/generic_values/option.rs
  type Item (line 15) | type Item = T;
  type Fallibility (line 17) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 20) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 31) | fn push_to_vec_with_idx(
  method push_to_bag (line 43) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 55) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 70) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 84) | fn next(self) -> Next<Self> {
  method map (line 91) | fn map<M, O>(
  method filter (line 102) | fn filter<F>(
  method flat_map (line 113) | fn flat_map<Fm, Vo>(
  method filter_map (line 125) | fn filter_map<Fm, O>(
  method whilst (line 138) | fn whilst(
  method map_while_ok (line 154) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 164) | fn u_map<U, M, O>(
  method u_filter (line 176) | fn u_filter<U, F>(
  method u_flat_map (line 187) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 199) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/option_result.rs
  type OptionResult (line 9) | pub struct OptionResult<T, E>(pub(crate) Option<Result<T, E>>)
  type Item (line 17) | type Item = T;
  type Fallibility (line 19) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 21) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 35) | fn push_to_vec_with_idx(
  method push_to_bag (line 50) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 65) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 81) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 97) | fn next(self) -> Next<Self> {

FILE: src/generic_values/result.rs
  type Item (line 19) | type Item = T;
  type Fallibility (line 21) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 23) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 36) | fn push_to_vec_with_idx(
  method push_to_bag (line 50) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 64) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 79) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 94) | fn next(self) -> Next<Self> {

FILE: src/generic_values/runner_results/collect_arbitrary.rs
  type ArbitraryPush (line 4) | pub enum ArbitraryPush<F: Fallibility> {
  type ThreadCollectArbitrary (line 10) | pub enum ThreadCollectArbitrary<F>
  function into_result (line 20) | pub fn into_result(self) -> Result<(), F::Error> {
  function fmt (line 29) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  type ParallelCollectArbitrary (line 38) | pub enum ParallelCollectArbitrary<V, P>
  function fmt (line 57) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  function into_result (line 73) | pub fn into_result(self) -> Result<P, <V::Fallibility as Fallibility>::E...

FILE: src/generic_values/runner_results/collect_ordered.rs
  type OrderedPush (line 9) | pub enum OrderedPush<F: Fallibility> {
  type ThreadCollect (line 15) | pub enum ThreadCollect<V>
  method fmt (line 32) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  function into_result (line 49) | pub fn into_result(self) -> Result<Self, <V::Fallibility as Fallibility>...
  type ParallelCollect (line 57) | pub enum ParallelCollect<V, P>
  function fmt (line 79) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  function reduce (line 103) | pub fn reduce(results: Vec<ThreadCollect<V>>, mut pinned_vec: P) -> Self {
  function into_result (line 132) | pub fn into_result(self) -> Result<P, <V::Fallibility as Fallibility>::E...

FILE: src/generic_values/runner_results/collect_sequential.rs
  type SequentialPush (line 5) | pub enum SequentialPush<F: Fallibility> {
  function sequential_push_to_stop (line 12) | pub fn sequential_push_to_stop(self) -> Option<Stop<Never>> {
  function sequential_push_to_stop (line 21) | pub fn sequential_push_to_stop(self) -> Option<Stop<E>> {

FILE: src/generic_values/runner_results/fallibility.rs
  type Fallibility (line 10) | pub trait Fallibility: Sized {
    method ordered_push_to_stop (line 13) | fn ordered_push_to_stop(ordered_push: OrderedPush<Self>) -> Option<Sto...
    method arbitrary_push_to_stop (line 15) | fn arbitrary_push_to_stop(arbitrary_push: ArbitraryPush<Self>) -> Opti...
    method sequential_push_to_stop (line 17) | fn sequential_push_to_stop(sequential_push: SequentialPush<Self>) -> O...
    method reduce_to_stop (line 19) | fn reduce_to_stop<V>(reduce: Reduce<V>) -> Result<Option<V::Item>, Sto...
    method reduce_results (line 23) | fn reduce_results<T>(results: Vec<Result<T, Self::Error>>) -> Result<V...
    type Error (line 29) | type Error = Never;
    method ordered_push_to_stop (line 32) | fn ordered_push_to_stop(ordered_push: OrderedPush<Self>) -> Option<Sto...
    method arbitrary_push_to_stop (line 40) | fn arbitrary_push_to_stop(arbitrary_push: ArbitraryPush<Self>) -> Opti...
    method sequential_push_to_stop (line 48) | fn sequential_push_to_stop(sequential_push: SequentialPush<Self>) -> O...
    method reduce_to_stop (line 56) | fn reduce_to_stop<V>(reduce: Reduce<V>) -> Result<Option<V::Item>, Sto...
    method reduce_results (line 66) | fn reduce_results<T>(results: Vec<Result<T, Self::Error>>) -> Result<V...
    type Error (line 79) | type Error = E;
    method ordered_push_to_stop (line 82) | fn ordered_push_to_stop(ordered_push: OrderedPush<Self>) -> Option<Sto...
    method arbitrary_push_to_stop (line 93) | fn arbitrary_push_to_stop(arbitrary_push: ArbitraryPush<Self>) -> Opti...
    method sequential_push_to_stop (line 102) | fn sequential_push_to_stop(sequential_push: SequentialPush<Self>) -> O...
    method reduce_to_stop (line 111) | fn reduce_to_stop<V>(reduce: Reduce<V>) -> Result<Option<V::Item>, Sto...
    method reduce_results (line 122) | fn reduce_results<T>(results: Vec<Result<T, Self::Error>>) -> Result<V...
  type Infallible (line 26) | pub struct Infallible;
  type Fallible (line 76) | pub struct Fallible<E>(PhantomData<E>);
  type Never (line 134) | pub enum Never {}

FILE: src/generic_values/runner_results/next.rs
  type Next (line 3) | pub enum Next<V: Values> {
  type NextWithIdx (line 13) | pub enum NextWithIdx<V: Values> {
  type NextSuccess (line 27) | pub enum NextSuccess<T> {
  function reduce (line 33) | pub fn reduce(results: impl IntoIterator<Item = Self>) -> Option<(usize,...

FILE: src/generic_values/runner_results/reduce.rs
  type Reduce (line 3) | pub enum Reduce<V: Values> {
  function into_result (line 16) | pub fn into_result(self) -> Result<Option<V::Item>, <V::Fallibility as F...
  function fmt (line 26) | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

FILE: src/generic_values/runner_results/stop.rs
  type Stop (line 3) | pub enum Stop<E> {
  type StopWithIdx (line 8) | pub enum StopWithIdx<E> {
  type StopReduce (line 13) | pub enum StopReduce<V: Values> {

FILE: src/generic_values/transformable_values.rs
  type TransformableValues (line 3) | pub trait TransformableValues: Values {
    method map (line 4) | fn map<M, O>(
    method filter (line 11) | fn filter<F>(
    method flat_map (line 18) | fn flat_map<Fm, Vo>(
    method filter_map (line 26) | fn filter_map<Fm, O>(
    method whilst (line 33) | fn whilst(
    method map_while_ok (line 38) | fn map_while_ok<Mr, O, E>(
    method u_map (line 46) | fn u_map<U, M, O>(
    method u_filter (line 54) | fn u_filter<U, F>(
    method u_flat_map (line 62) | fn u_flat_map<U, Fm, Vo>(
    method u_filter_map (line 71) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/values.rs
  type Values (line 10) | pub trait Values: Sized {
    method push_to_pinned_vec (line 15) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self:...
    method push_to_vec_with_idx (line 19) | fn push_to_vec_with_idx(
    method push_to_bag (line 25) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitra...
    method acc_reduce (line 30) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<S...
    method u_acc_reduce (line 34) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce...
    method next (line 38) | fn next(self) -> Next<Self>;
    method ordered_push_to_stop (line 43) | fn ordered_push_to_stop(
    method arbitrary_push_to_stop (line 50) | fn arbitrary_push_to_stop(
    method sequential_push_to_stop (line 57) | fn sequential_push_to_stop(
    method reduce_to_stop (line 64) | fn reduce_to_stop(reduce: Reduce<Self>) -> Result<Option<Self::Item>, ...

FILE: src/generic_values/vector.rs
  type Vector (line 13) | pub struct Vector<I>(pub I)
  type Item (line 21) | type Item = I::Item;
  type Fallibility (line 23) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 26) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 37) | fn push_to_vec_with_idx(
  method push_to_bag (line 49) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 61) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 77) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 93) | fn next(self) -> Next<Self> {
  method map (line 105) | fn map<M, O>(
  method filter (line 116) | fn filter<F>(
  method flat_map (line 127) | fn flat_map<Fm, Vo>(
  method filter_map (line 139) | fn filter_map<Fm, O>(
  method whilst (line 149) | fn whilst(
  method map_while_ok (line 163) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 172) | fn u_map<U, M, O>(
  method u_filter (line 183) | fn u_filter<U, F>(
  method u_flat_map (line 194) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 206) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/vector_result.rs
  type VectorResult (line 10) | pub struct VectorResult<I, T, E>(pub(crate) I)
  type Item (line 20) | type Item = T;
  type Fallibility (line 22) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 24) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 37) | fn push_to_vec_with_idx(
  method push_to_bag (line 51) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 65) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 95) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 125) | fn next(self) -> Next<Self> {

FILE: src/generic_values/whilst_atom.rs
  type WhilstAtom (line 11) | pub enum WhilstAtom<T> {
  function new (line 18) | pub fn new(value: T, whilst: impl Fn(&T) -> bool) -> Self {
  type Item (line 27) | type Item = T;
  type Fallibility (line 29) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 31) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 44) | fn push_to_vec_with_idx(
  method push_to_bag (line 58) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 72) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 87) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 102) | fn next(self) -> Next<Self> {
  method map (line 111) | fn map<M, O>(
  method filter (line 124) | fn filter<F>(
  method flat_map (line 140) | fn flat_map<Fm, Vo>(
  method filter_map (line 152) | fn filter_map<Fm, O>(
  method whilst (line 168) | fn whilst(
  method map_while_ok (line 184) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 198) | fn u_map<U, M, O>(
  method u_filter (line 212) | fn u_filter<U, F>(
  method u_flat_map (line 229) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 242) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/whilst_atom_result.rs
  type WhilstAtomResult (line 9) | pub enum WhilstAtomResult<T, E>
  type Item (line 22) | type Item = T;
  type Fallibility (line 24) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 26) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 40) | fn push_to_vec_with_idx(
  method push_to_bag (line 55) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 70) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 86) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 102) | fn next(self) -> Next<Self> {

FILE: src/generic_values/whilst_iterators/whilst_atom_flat_map.rs
  type WhilstAtomFlatMapIter (line 3) | pub struct WhilstAtomFlatMapIter<Vo>
  function from_atom (line 14) | pub fn from_atom<T, Fm>(atom: WhilstAtom<T>, flat_map: Fm) -> Self
  function u_from_atom (line 25) | pub fn u_from_atom<U, T, Fm>(u: *mut U, atom: WhilstAtom<T>, flat_map: F...
  type Item (line 41) | type Item = WhilstAtom<Vo::Item>;
  method next (line 43) | fn next(&mut self) -> Option<Self::Item> {

FILE: src/generic_values/whilst_iterators/whilst_option_flat_map.rs
  type WhilstOptionFlatMapIter (line 3) | pub struct WhilstOptionFlatMapIter<Vo>
  function from_option (line 14) | pub fn from_option<T, Fm>(atom: WhilstOption<T>, flat_map: Fm) -> Self
  function u_from_option (line 26) | pub fn u_from_option<U, T, Fm>(u: *mut U, atom: WhilstOption<T>, flat_ma...
  type Item (line 43) | type Item = WhilstAtom<Vo::Item>;
  method next (line 45) | fn next(&mut self) -> Option<Self::Item> {

FILE: src/generic_values/whilst_option.rs
  type WhilstOption (line 11) | pub enum WhilstOption<T> {
  type Item (line 18) | type Item = T;
  type Fallibility (line 20) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 22) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 36) | fn push_to_vec_with_idx(
  method push_to_bag (line 51) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 66) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 82) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 98) | fn next(self) -> Next<Self> {
  method map (line 108) | fn map<M, O>(
  method filter (line 122) | fn filter<F>(
  method flat_map (line 139) | fn flat_map<Fm, Vo>(
  method filter_map (line 151) | fn filter_map<Fm, O>(
  method whilst (line 168) | fn whilst(
  method map_while_ok (line 185) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 200) | fn u_map<U, M, O>(
  method u_filter (line 215) | fn u_filter<U, F>(
  method u_flat_map (line 233) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 246) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/whilst_option_result.rs
  type WhilstOptionResult (line 9) | pub enum WhilstOptionResult<T, E>
  type Item (line 23) | type Item = T;
  type Fallibility (line 25) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 27) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 42) | fn push_to_vec_with_idx(
  method push_to_bag (line 58) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 74) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 91) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 108) | fn next(self) -> Next<Self> {

FILE: src/generic_values/whilst_vector.rs
  type WhilstVector (line 15) | pub struct WhilstVector<I, T>(pub(crate) I)
  type Item (line 23) | type Item = T;
  type Fallibility (line 25) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 27) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 40) | fn push_to_vec_with_idx(
  method push_to_bag (line 54) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 68) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 98) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 128) | fn next(self) -> Next<Self> {
  method map (line 143) | fn map<M, O>(
  method filter (line 157) | fn filter<F>(
  method flat_map (line 174) | fn flat_map<Fm, Vo>(
  method filter_map (line 189) | fn filter_map<Fm, O>(
  method whilst (line 203) | fn whilst(
  method map_while_ok (line 220) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 232) | fn u_map<U, M, O>(
  method u_filter (line 247) | fn u_filter<U, F>(
  method u_flat_map (line 265) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 281) | fn u_filter_map<U, Fm, O>(

FILE: src/generic_values/whilst_vector_result.rs
  type WhilstVectorResult (line 10) | pub struct WhilstVectorResult<I, T, E>(pub(crate) I)
  type Item (line 20) | type Item = T;
  type Fallibility (line 22) | type Fallibility = Fallible<E>;
  method push_to_pinned_vec (line 24) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 40) | fn push_to_vec_with_idx(
  method push_to_bag (line 57) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 72) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 106) | fn u_acc_reduce<U, X>(self, u: *mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 140) | fn next(self) -> Next<Self> {

FILE: src/heap_sort.rs
  function heap_sort_into (line 6) | pub fn heap_sort_into<T, P>(

FILE: src/into_par_iter.rs
  type IntoParIter (line 28) | pub trait IntoParIter: IntoConcurrentIter {
    method into_par (line 50) | fn into_par(self) -> Par<Self::IntoIter, DefaultRunner>;
    method into_par (line 57) | fn into_par(self) -> Par<Self::IntoIter, DefaultRunner> {
  type Item (line 63) | type Item = I::Item;
  type IntoIter (line 65) | type IntoIter = I;
  method into_con_iter (line 67) | fn into_con_iter(self) -> Self::IntoIter {

FILE: src/iter/recursive/into_par_rec_iter.rs
  type IntoParIterRec (line 19) | pub trait IntoParIterRec
    method into_par_rec (line 214) | fn into_par_rec<E>(
    method into_par_rec_exact (line 411) | fn into_par_rec_exact<E>(
    method into_par_rec (line 425) | fn into_par_rec<E>(
    method into_par_rec_exact (line 436) | fn into_par_rec_exact<E>(

FILE: src/iter/recursive/rec_par_iter.rs
  type Rec (line 10) | type Rec<T, E> = ConcurrentRecursiveIter<T, E>;
  function linearize (line 31) | pub fn linearize(self) -> Par<ConIterVec<T>, R> {
  function linearize (line 60) | pub fn linearize(self) -> ParMap<ConIterVec<T>, O, M1, R> {
  function linearize (line 90) | pub fn linearize(self) -> ParXap<ConIterVec<T>, Vo, X1, R> {

FILE: src/iter/special_iterators.rs
  type ParEmpty (line 5) | pub type ParEmpty<T, R = DefaultRunner> = Par<ConIterEmpty<T>, R>;
  function empty (line 8) | pub fn empty<T: Send + Sync>() -> ParEmpty<T> {

FILE: src/iter_into_par_iter.rs
  type IterIntoParIter (line 61) | pub trait IterIntoParIter: Iterator {
    method iter_into_par (line 119) | fn iter_into_par(self) -> Par<ConIterOfIter<Self>, DefaultRunner>
    method iter_into_par (line 130) | fn iter_into_par(self) -> Par<ConIterOfIter<Self>, DefaultRunner> {

FILE: src/par_iter.rs
  type ParIter (line 18) | pub trait ParIter<R = DefaultRunner>: Sized + Send + Sync
    method con_iter (line 26) | fn con_iter(&self) -> &impl ConcurrentIter;
    method params (line 79) | fn params(&self) -> Params;
    method num_threads (line 147) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
    method chunk_size (line 214) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
    method iteration_order (line 248) | fn iteration_order(self, order: IterationOrder) -> Self;
    method with_runner (line 312) | fn with_runner<Q: ParallelRunner>(self, runner: Q) -> impl ParIter<Q, ...
    method with_pool (line 382) | fn with_pool<P: ParThreadPool>(
    method using (line 603) | fn using<'using, U, F>(
    method using_clone (line 624) | fn using_clone<U>(
    method into_fallible_result (line 673) | fn into_fallible_result<T, E>(self) -> impl ParIterResult<R, Item = T,...
    method into_fallible_option (line 717) | fn into_fallible_option<T>(self) -> impl ParIterOption<R, Item = T>
    method map (line 743) | fn map<Out, Map>(self, map: Map) -> impl ParIter<R, Item = Out>
    method filter (line 761) | fn filter<Filter>(self, filter: Filter) -> impl ParIter<R, Item = Self...
    method flat_map (line 780) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIter<R,...
    method filter_map (line 806) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl Par...
    method inspect (line 867) | fn inspect<Operation>(self, operation: Operation) -> impl ParIter<R, I...
    method take_while (line 902) | fn take_while<While>(self, take_while: While) -> impl ParIter<R, Item ...
    method map_while (line 930) | fn map_while<Out, MapWhile>(self, map_while: MapWhile) -> impl ParIter...
    method copied (line 959) | fn copied<'a, T>(self) -> impl ParIter<R, Item = T>
    method cloned (line 990) | fn cloned<'a, T>(self) -> impl ParIter<R, Item = T>
    method flatten (line 1041) | fn flatten(self) -> impl ParIter<R, Item = <Self::Item as IntoIterator...
    method collect_into (line 1074) | fn collect_into<C>(self, output: C) -> C
    method collect (line 1098) | fn collect<C>(self) -> C
    method reduce (line 1123) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
    method all (line 1152) | fn all<Predicate>(self, predicate: Predicate) -> bool
    method any (line 1185) | fn any<Predicate>(self, predicate: Predicate) -> bool
    method count (line 1203) | fn count(self) -> usize {
    method for_each (line 1241) | fn for_each<Operation>(self, operation: Operation)
    method max (line 1264) | fn max(self) -> Option<Self::Item>
    method max_by (line 1283) | fn max_by<Compare>(self, compare: Compare) -> Option<Self::Item>
    method max_by_key (line 1307) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Option<Self::Item>
    method min (line 1335) | fn min(self) -> Option<Self::Item>
    method min_by (line 1354) | fn min_by<Compare>(self, compare: Compare) -> Option<Self::Item>
    method min_by_key (line 1378) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Option<Self::Item>
    method sum (line 1411) | fn sum<Out>(self) -> Out
    method first (line 1467) | fn first(self) -> Option<Self::Item>
    method find (line 1513) | fn find<Predicate>(self, predicate: Predicate) -> Option<Self::Item>

FILE: src/par_iter_option.rs
  type ParIterOption (line 126) | pub trait ParIterOption<R = DefaultRunner>
    method num_threads (line 143) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
    method chunk_size (line 154) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
    method iteration_order (line 159) | fn iteration_order(self, order: IterationOrder) -> Self;
    method with_runner (line 167) | fn with_runner<Q: ParallelRunner>(
    method with_pool (line 179) | fn with_pool<P: ParThreadPool>(
    method map (line 216) | fn map<Out, Map>(self, map: Map) -> impl ParIterOption<R, Item = Out>
    method filter (line 246) | fn filter<Filter>(self, filter: Filter) -> impl ParIterOption<R, Item ...
    method flat_map (line 286) | fn flat_map<IOut, FlatMap>(self, flat_map: FlatMap) -> impl ParIterOpt...
    method filter_map (line 327) | fn filter_map<Out, FilterMap>(self, filter_map: FilterMap) -> impl Par...
    method inspect (line 407) | fn inspect<Operation>(self, operation: Operation) -> impl ParIterOptio...
    method collect_into (line 454) | fn collect_into<C>(self, output: C) -> Option<C>
    method collect (line 496) | fn collect<C>(self) -> Option<C>
    method reduce (line 539) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Option<Self::Item>>
    method all (line 597) | fn all<Predicate>(self, predicate: Predicate) -> Option<bool>
    method any (line 661) | fn any<Predicate>(self, predicate: Predicate) -> Option<bool>
    method count (line 696) | fn count(self) -> Option<usize>
    method for_each (line 742) | fn for_each<Operation>(self, operation: Operation) -> Option<()>
    method max (line 769) | fn max(self) -> Option<Option<Self::Item>>
    method max_by (line 811) | fn max_by<Compare>(self, compare: Compare) -> Option<Option<Self::Item>>
    method max_by_key (line 860) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Option<Option<Self::I...
    method min (line 892) | fn min(self) -> Option<Option<Self::Item>>
    method min_by (line 934) | fn min_by<Compare>(self, compare: Compare) -> Option<Option<Self::Item>>
    method min_by_key (line 983) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Option<Option<Sel...
    method sum (line 1031) | fn sum<Out>(self) -> Option<Out>
    method first (line 1076) | fn first(self) -> Option<Option<Self::Item>>
    method find (line 1115) | fn find<Predicate>(self, predicate: Predicate) -> Option<Option<Self::...
  type IntoOption (line 1125) | pub trait IntoOption<T> {
    method into_option (line 1126) | fn into_option(self) -> Option<T>;
    method into_result_with_unit_err (line 1128) | fn into_result_with_unit_err(self) -> Result<T, ()>;
  function into_option (line 1133) | fn into_option(self) -> Option<T> {
  function into_result_with_unit_err (line 1138) | fn into_result_with_unit_err(self) -> Result<T, ()> {
  type ResultIntoOption (line 1146) | pub(crate) trait ResultIntoOption<T> {
    method into_option (line 1147) | fn into_option(self) -> Option<T>;
  function into_option (line 1152) | fn into_option(self) -> Option<T> {

FILE: src/par_iter_result.rs
  type ParIterResult (line 132) | pub trait ParIterResult<R = DefaultRunner>
    method con_iter_len (line 149) | fn con_iter_len(&self) -> Option<usize>;
    method into_regular_par (line 152) | fn into_regular_par(self) -> Self::RegularParIter;
    method from_regular_par (line 155) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self;
    method num_threads (line 167) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self
    method chunk_size (line 183) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self
    method iteration_order (line 193) | fn iteration_order(self, order: IterationOrder) -> Self
    method with_runner (line 206) | fn with_runner<Q: ParallelRunner>(
    method with_pool (line 218) | fn with_pool<P: ParThreadPool>(
    method map (line 255) | fn map<Out, Map>(self, map: Map) -> impl ParIterResult<R, Item = Out, ...
    method filter (line 290) | fn filter<Filter>(
    method flat_map (line 344) | fn flat_map<IOut, FlatMap>(
    method filter_map (line 396) | fn filter_map<Out, FilterMap>(
    method inspect (line 487) | fn inspect<Operation>(
    method collect_into (line 545) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
    method collect (line 588) | fn collect<C>(self) -> Result<C, Self::Err>
    method reduce (line 644) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, ...
    method all (line 703) | fn all<Predicate>(self, predicate: Predicate) -> Result<bool, Self::Err>
    method any (line 768) | fn any<Predicate>(self, predicate: Predicate) -> Result<bool, Self::Err>
    method count (line 804) | fn count(self) -> Result<usize, Self::Err>
    method for_each (line 851) | fn for_each<Operation>(self, operation: Operation) -> Result<(), Self:...
    method max (line 879) | fn max(self) -> Result<Option<Self::Item>, Self::Err>
    method max_by (line 922) | fn max_by<Compare>(self, compare: Compare) -> Result<Option<Self::Item...
    method max_by_key (line 972) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Result<Option<Self::I...
    method min (line 1005) | fn min(self) -> Result<Option<Self::Item>, Self::Err>
    method min_by (line 1048) | fn min_by<Compare>(self, compare: Compare) -> Result<Option<Self::Item...
    method min_by_key (line 1098) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Result<Option<Sel...
    method sum (line 1154) | fn sum<Out>(self) -> Result<Out, Self::Err>
    method first (line 1197) | fn first(self) -> Result<Option<Self::Item>, Self::Err>
    method find (line 1237) | fn find<Predicate>(self, predicate: Predicate) -> Result<Option<Self::...
  type IntoResult (line 1248) | pub trait IntoResult<T, E> {
    method into_result (line 1249) | fn into_result(self) -> Result<T, E>;
  function into_result (line 1254) | fn into_result(self) -> Result<T, E> {

FILE: src/par_thread_pool.rs
  type ParThreadPool (line 95) | pub trait ParThreadPool {
    method run_in_scope (line 103) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'sco...
    method scoped_computation (line 110) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
    method max_num_threads (line 116) | fn max_num_threads(&self) -> NonZeroUsize;
  type ParThreadPoolCompute (line 121) | pub trait ParThreadPoolCompute: ParThreadPool {
    method map_in_pool (line 122) | fn map_in_pool<F, S, M, T>(
    method run_in_pool (line 156) | fn run_in_pool<S, F>(&mut self, do_spawn: S, thread_do: F) -> NumSpawned

FILE: src/parallel_drainable.rs
  type ParallelDrainableOverSlice (line 25) | pub trait ParallelDrainableOverSlice: ConcurrentDrainableOverSlice {
    method par_drain (line 46) | fn par_drain<R>(

FILE: src/parallelizable.rs
  type Parallelizable (line 35) | pub trait Parallelizable: ConcurrentIterable {
    method par (line 64) | fn par(&self) -> Par<<Self as ConcurrentIterable>::Iter, DefaultRunner> {

FILE: src/parallelizable_collection.rs
  type ParallelizableCollection (line 38) | pub trait ParallelizableCollection: ConcurrentCollection {
    method par (line 74) | fn par(

FILE: src/parallelizable_collection_mut.rs
  type ParallelizableCollectionMut (line 47) | pub trait ParallelizableCollectionMut: ConcurrentCollectionMut + Paralle...
    method par_mut (line 62) | fn par_mut(&mut self) -> impl ParIter<DefaultRunner, Item = &mut Self:...

FILE: src/parameters/chunk_size.rs
  type ChunkSize (line 48) | pub enum ChunkSize {
    method from (line 68) | fn from(value: usize) -> Self {

FILE: src/parameters/iteration_order.rs
  type IterationOrder (line 20) | pub enum IterationOrder {

FILE: src/parameters/num_threads.rs
  type NumThreads (line 22) | pub enum NumThreads {
    method from (line 47) | fn from(value: usize) -> Self {
    method sequential (line 60) | pub const fn sequential() -> Self {
    method is_sequential (line 67) | pub fn is_sequential(self) -> bool {
  constant ONE (line 40) | const ONE: NonZeroUsize = NonZeroUsize::new(1).expect("seq=1 is positive");

FILE: src/parameters/params.rs
  type Params (line 5) | pub struct Params {
    method new (line 23) | pub fn new(
    method is_sequential (line 38) | pub fn is_sequential(self) -> bool {
    method with_num_threads (line 44) | pub(crate) fn with_num_threads(self, num_threads: impl Into<NumThreads...
    method with_chunk_size (line 52) | pub(crate) fn with_chunk_size(self, chunk_size: impl Into<ChunkSize>) ...
    method with_collect_ordering (line 60) | pub(crate) fn with_collect_ordering(self, iteration_order: IterationOr...

FILE: src/runner/computation_kind.rs
  type ComputationKind (line 3) | pub enum ComputationKind {

FILE: src/runner/implementations/pond.rs
  type PondPool (line 13) | pub struct PondPool(Pool, NonZeroUsize);
    method new_threads_unbounded (line 18) | pub fn new_threads_unbounded(num_threads: usize) -> Self {
    method inner (line 26) | pub fn inner(&self) -> &Pool {
    method inner_mut (line 31) | pub fn inner_mut(&mut self) -> &mut Pool {
    method into_inner (line 36) | pub fn into_inner(self) -> Pool {
  type ScopeRef (line 42) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 48) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 57) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 65) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 71) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 77) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 86) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 94) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/implementations/poolite.rs
  type ScopeRef (line 6) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 12) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 21) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 29) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 35) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 41) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 50) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 58) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/implementations/rayon_core.rs
  type ScopeRef (line 6) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 12) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 21) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 29) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 35) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 41) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 50) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 58) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/implementations/runner_with_pool.rs
  type RunnerWithPool (line 106) | pub struct RunnerWithPool<P, R = DefaultExecutor>
  method default (line 120) | fn default() -> Self {
  function from (line 129) | fn from(pool: P) -> Self {
  function into_inner_pool (line 186) | pub fn into_inner_pool(self) -> P {
  function with_executor (line 191) | pub fn with_executor<Q: ParallelExecutor>(self) -> RunnerWithPool<P, Q> {
  function with_diagnostics (line 241) | pub fn with_diagnostics(self) -> RunnerWithPool<P, ParallelExecutorWithD...
  type Executor (line 254) | type Executor = R;
  type ThreadPool (line 256) | type ThreadPool = P;
  method thread_pool (line 258) | fn thread_pool(&self) -> &Self::ThreadPool {
  method thread_pool_mut (line 262) | fn thread_pool_mut(&mut self) -> &mut Self::ThreadPool {

FILE: src/runner/implementations/scoped_pool.rs
  type ScopeRef (line 6) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 12) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 21) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 29) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 35) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 41) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 50) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 58) | fn max_num_threads(&self) -> core::num::NonZeroUsize {

FILE: src/runner/implementations/scoped_threadpool.rs
  type ScopeRef (line 6) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 12) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 21) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 29) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 35) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 41) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 50) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 58) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/implementations/sequential.rs
  type SequentialPool (line 14) | pub struct SequentialPool;
  type ScopeRef (line 17) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 23) | fn run_in_scope<'s, 'env, 'scope, W>(_: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 32) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 40) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/implementations/std_runner.rs
  constant MAX_UNSET_NUM_THREADS (line 4) | const MAX_UNSET_NUM_THREADS: NonZeroUsize = NonZeroUsize::new(8).expect(...
  type StdDefaultPool (line 22) | pub struct StdDefaultPool {
    method with_max_num_threads (line 32) | pub fn with_max_num_threads(max_num_threads: NonZeroUsize) -> Self {
  method default (line 42) | fn default() -> Self {
  type ScopeRef (line 59) | type ScopeRef<'s, 'env, 'scope>
  method max_num_threads (line 65) | fn max_num_threads(&self) -> NonZeroUsize {
  method scoped_computation (line 69) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method run_in_scope (line 77) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  type ScopeRef (line 88) | type ScopeRef<'s, 'env, 'scope>
  method max_num_threads (line 94) | fn max_num_threads(&self) -> NonZeroUsize {
  method scoped_computation (line 98) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method run_in_scope (line 106) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...

FILE: src/runner/implementations/tests/pond.rs
  constant N (line 9) | const N: [usize; 2] = [37, 125];
  constant N (line 11) | const N: [usize; 2] = [1025, 4735];
  function pool_pond_map (line 21) | fn pool_pond_map(n: usize, nt: usize, chunk: usize, ordering: IterationO...

FILE: src/runner/implementations/tests/poolite.rs
  constant N (line 7) | const N: [usize; 2] = [37, 125];
  constant N (line 9) | const N: [usize; 2] = [1025, 4735];
  function pool_poolite_map (line 19) | fn pool_poolite_map(n: usize, nt: usize, chunk: usize, ordering: Iterati...

FILE: src/runner/implementations/tests/rayon_core.rs
  constant N (line 6) | const N: [usize; 2] = [37, 125];
  constant N (line 8) | const N: [usize; 2] = [1025, 4735];
  function pool_rayon_map (line 18) | fn pool_rayon_map(n: usize, nt: usize, chunk: usize, ordering: Iteration...

FILE: src/runner/implementations/tests/scoped_pool.rs
  constant N (line 7) | const N: [usize; 2] = [37, 125];
  constant N (line 9) | const N: [usize; 2] = [1025, 4735];
  function pool_scoped_pool_map (line 19) | fn pool_scoped_pool_map(n: usize, nt: usize, chunk: usize, ordering: Ite...

FILE: src/runner/implementations/tests/scoped_threadpool.rs
  constant N (line 7) | const N: [usize; 2] = [37, 125];
  constant N (line 9) | const N: [usize; 2] = [1025, 4735];
  function pool_scoped_threadpool_map (line 19) | fn pool_scoped_threadpool_map(n: usize, nt: usize, chunk: usize, orderin...

FILE: src/runner/implementations/tests/sequential.rs
  constant N (line 6) | const N: [usize; 2] = [37, 125];
  constant N (line 8) | const N: [usize; 2] = [1025, 4735];
  function pool_scoped_threadpool_map (line 16) | fn pool_scoped_threadpool_map(n: usize, _: usize, chunk: usize, ordering...

FILE: src/runner/implementations/tests/std.rs
  constant N (line 9) | const N: [usize; 2] = [37, 125];
  constant N (line 11) | const N: [usize; 2] = [1025, 4735];
  function pool_scoped_threadpool_map (line 19) | fn pool_scoped_threadpool_map(n: usize, _: usize, chunk: usize, ordering...

FILE: src/runner/implementations/tests/utils.rs
  function run_map (line 8) | pub fn run_map(n: usize, chunk: usize, ordering: IterationOrder, mut orc...

FILE: src/runner/implementations/tests/yastl.rs
  constant N (line 10) | const N: [usize; 2] = [37, 125];
  constant N (line 12) | const N: [usize; 2] = [1025, 4735];
  function pool_yastl_map (line 22) | fn pool_yastl_map(n: usize, nt: usize, chunk: usize, ordering: Iteration...

FILE: src/runner/implementations/yastl.rs
  type YastlPool (line 15) | pub struct YastlPool(Pool, NonZeroUsize);
    method new (line 19) | pub fn new(num_threads: usize) -> Self {
    method with_config (line 28) | pub fn with_config(num_threads: usize, config: ThreadConfig) -> Self {
    method inner (line 36) | pub fn inner(&self) -> &Pool {
    method inner_mut (line 41) | pub fn inner_mut(&mut self) -> &mut Pool {
    method into_inner (line 46) | pub fn into_inner(self) -> Pool {
  type ScopeRef (line 52) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 58) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 67) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 75) | fn max_num_threads(&self) -> NonZeroUsize {
  type ScopeRef (line 81) | type ScopeRef<'s, 'env, 'scope>
  method run_in_scope (line 87) | fn run_in_scope<'s, 'env, 'scope, W>(s: &Self::ScopeRef<'s, 'env, 'scope...
  method scoped_computation (line 96) | fn scoped_computation<'env, 'scope, F>(&'env mut self, f: F)
  method max_num_threads (line 104) | fn max_num_threads(&self) -> NonZeroUsize {

FILE: src/runner/mod.rs
  type DefaultPool (line 29) | pub type DefaultPool = StdDefaultPool;
  type DefaultPool (line 35) | pub type DefaultPool = SequentialPool;
  type DefaultRunner (line 41) | pub type DefaultRunner = RunnerWithPool<DefaultPool>;

FILE: src/runner/num_spawned.rs
  type NumSpawned (line 3) | pub struct NumSpawned(usize);
    method zero (line 7) | pub fn zero() -> Self {
    method increment (line 12) | pub fn increment(&mut self) {
    method into_inner (line 17) | pub fn into_inner(self) -> usize {
    type Output (line 23) | type Output = usize;
    method rem (line 25) | fn rem(self, rhs: Self) -> Self::Output {

FILE: src/runner/parallel_runner.rs
  type ParallelRunner (line 12) | pub trait ParallelRunner {
    method new_executor (line 20) | fn new_executor(
    method thread_pool (line 31) | fn thread_pool(&self) -> &Self::ThreadPool;
    method thread_pool_mut (line 34) | fn thread_pool_mut(&mut self) -> &mut Self::ThreadPool;
    method run_all (line 39) | fn run_all<I, F>(
    method map_all (line 68) | fn map_all<F, I, M, T>(
    method map_infallible (line 105) | fn map_infallible<I, M, T>(
    method max_num_threads_for_computation (line 123) | fn max_num_threads_for_computation(
    type Executor (line 154) | type Executor = O::Executor;
    type ThreadPool (line 156) | type ThreadPool = O::ThreadPool;
    method thread_pool (line 158) | fn thread_pool(&self) -> &Self::ThreadPool {
    method thread_pool_mut (line 162) | fn thread_pool_mut(&mut self) -> &mut Self::ThreadPool {
  type SharedStateOf (line 143) | pub(crate) type SharedStateOf<C> =
  type ThreadRunnerOf (line 145) | pub(crate) type ThreadRunnerOf<C> =

FILE: src/special_type_sets/sum.rs
  type Sum (line 4) | pub trait Sum<Output> {
    method zero (line 6) | fn zero() -> Output;
    method map (line 9) | fn map(a: Self) -> Output;
    method u_map (line 12) | fn u_map<U>(_: &mut U, a: Self) -> Output;
    method reduce (line 15) | fn reduce(a: Output, b: Output) -> Output;
    method u_reduce (line 18) | fn u_reduce<U>(_: &mut U, a: Output, b: Output) -> Output;
  method zero (line 25) | fn zero() -> X {
  method map (line 30) | fn map(a: Self) -> X {
  method u_map (line 35) | fn u_map<U>(_: &mut U, a: Self) -> X {
  method reduce (line 40) | fn reduce(a: X, b: X) -> X {
  method u_reduce (line 45) | fn u_reduce<U>(_: &mut U, a: X, b: X) -> X {
  function zero (line 55) | fn zero() -> X {
  function map (line 60) | fn map(a: Self) -> X {
  function u_map (line 65) | fn u_map<U>(_: &mut U, a: Self) -> X {
  function reduce (line 70) | fn reduce(a: X, b: X) -> X {
  function u_reduce (line 75) | fn u_reduce<U>(_: &mut U, a: X, b: X) -> X {
  function zero (line 85) | fn zero() -> X {
  function map (line 90) | fn map(a: Self) -> X {
  function u_map (line 95) | fn u_map<U>(_: &mut U, a: Self) -> X {
  function reduce (line 100) | fn reduce(a: X, b: X) -> X {
  function u_reduce (line 105) | fn u_reduce<U>(_: &mut U, a: X, b: X) -> X {

FILE: src/test_utils.rs
  constant N (line 3) | pub const N: &[usize] = &[8025, 42735];
  constant NT (line 6) | pub const NT: &[usize] = &[0, 1, 2, 4];
  constant CHUNK (line 9) | pub const CHUNK: &[usize] = &[0, 1, 64, 1024];
  constant N (line 13) | pub const N: &[usize] = &[57];
  constant NT (line 16) | pub const NT: &[usize] = &[1, 2];
  constant CHUNK (line 19) | pub const CHUNK: &[usize] = &[4];
  function test_n_nt_chunk (line 22) | pub fn test_n_nt_chunk<T>(n: &[usize], nt: &[usize], chunk: &[usize], te...

FILE: src/using/collect_into/collect.rs
  function map_collect_into (line 12) | pub fn map_collect_into<'using, U, R, I, O, M1, P>(
  function map_collect_into_seq (line 41) | fn map_collect_into_seq<'using, U, I, O, M1, P>(using: U, iter: I, map1:...
  function xap_collect_into (line 57) | pub fn xap_collect_into<'using, U, R, I, Vo, X1, P>(
  function xap_collect_into_seq (line 102) | fn xap_collect_into_seq<'using, U, I, Vo, X1, P>(
  function xap_try_collect_into (line 129) | pub fn xap_try_collect_into<'using, U, R, I, Vo, X1, P>(
  function xap_try_collect_into_seq (line 167) | fn xap_try_collect_into_seq<'using, U, I, Vo, X1, P>(

FILE: src/using/collect_into/fixed_vec.rs
  function u_m_collect_into (line 15) | fn u_m_collect_into<'using, U, R, I, M1>(
  function u_x_collect_into (line 33) | fn u_x_collect_into<'using, U, R, I, Vo, X1>(
  function u_x_try_collect_into (line 52) | fn u_x_try_collect_into<'using, U, R, I, Vo, X1>(

FILE: src/using/collect_into/split_vec.rs
  function u_m_collect_into (line 20) | fn u_m_collect_into<'using, U, R, I, M1>(
  function u_x_collect_into (line 39) | fn u_x_collect_into<'using, U, R, I, Vo, X1>(
  function u_x_try_collect_into (line 60) | fn u_x_try_collect_into<'using, U, R, I, Vo, X1>(

FILE: src/using/collect_into/u_par_collect_into.rs
  type UParCollectIntoCore (line 9) | pub trait UParCollectIntoCore<O>: ParCollectIntoCore<O> {
    method u_m_collect_into (line 10) | fn u_m_collect_into<'using, U, R, I, M1>(
    method u_x_collect_into (line 24) | fn u_x_collect_into<'using, U, R, I, Vo, X1>(
    method u_x_try_collect_into (line 39) | fn u_x_try_collect_into<'using, U, R, I, Vo, X1>(

FILE: src/using/collect_into/vec.rs
  function u_m_collect_into (line 18) | fn u_m_collect_into<'using, U, R, I, M1>(
  function u_x_collect_into (line 48) | fn u_x_collect_into<'using, U, R, I, Vo, X1>(
  function u_x_try_collect_into (line 68) | fn u_x_try_collect_into<'using, U, R, I, Vo, X1>(

FILE: src/using/computational_variants/tests/copied.rs
  function input (line 7) | fn input<O: FromIterator<usize>>(n: usize) -> O {
  function copied_cloned_empty (line 12) | fn copied_cloned_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_map (line 34) | fn copied_cloned_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_xap_flat_map (line 57) | fn copied_cloned_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function copied_cloned_xap_filter_map (line 80) | fn copied_cloned_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usiz...
  function copied_cloned_xap_filter_xap (line 103) | fn copied_cloned_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usiz...

FILE: src/using/computational_variants/tests/count.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function count_empty (line 14) | fn count_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_map (line 30) | fn count_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_flat_map (line 47) | fn count_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_filter_map (line 65) | fn count_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function count_xap_filter_xap (line 83) | fn count_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/fallible_option.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function fallible_option_collect_empty (line 14) | fn fallible_option_collect_empty(nt: &[usize], chunk: &[usize]) {
  function fallible_option_collect_partial_success (line 35) | fn fallible_option_collect_partial_success(n: &[usize], nt: &[usize], ch...
  function fallible_option_collect_complete_success (line 57) | fn fallible_option_collect_complete_success(n: &[usize], nt: &[usize], c...

FILE: src/using/computational_variants/tests/fallible_result.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  type MyErr (line 14) | struct MyErr(String);
    method new (line 16) | fn new() -> Self {
  function fallible_result_collect_empty (line 22) | fn fallible_result_collect_empty(nt: &[usize], chunk: &[usize]) {
  function fallible_result_collect_partial_success (line 43) | fn fallible_result_collect_partial_success(n: &[usize], nt: &[usize], ch...
  function fallible_result_collect_complete_success (line 68) | fn fallible_result_collect_complete_success(n: &[usize], nt: &[usize], c...

FILE: src/using/computational_variants/tests/flatten.rs
  function flatten_empty (line 9) | fn flatten_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_map (line 32) | fn flatten_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_xap_filter_map (line 53) | fn flatten_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function flatten_xap_filter_xap (line 82) | fn flatten_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/for_each.rs
  function input (line 9) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sorted (line 14) | fn sorted(mut x: Vec<String>) -> Vec<String> {
  function for_each_empty (line 20) | fn for_each_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_map (line 40) | fn for_each_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_flat_map (line 65) | fn for_each_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_filter_map (line 90) | fn for_each_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function for_each_xap_filter_xap (line 115) | fn for_each_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/inspect.rs
  function input (line 9) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sorted (line 14) | fn sorted(mut x: Vec<String>) -> Vec<String> {
  function inspect_empty (line 20) | fn inspect_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_map (line 44) | fn inspect_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_flat_map (line 72) | fn inspect_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_filter_map (line 100) | fn inspect_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function inspect_xap_filter_xap (line 128) | fn inspect_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/iter_consuming.rs
  constant N_OFFSET (line 12) | const N_OFFSET: usize = 13;
  function offset (line 14) | fn offset() -> Vec<String> {
  function input (line 18) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 23) | fn expected(
  function empty_collect_into (line 45) | fn empty_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ...
  function empty_collect (line 70) | fn empty_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[u...
  function map_collect_into (line 97) | fn map_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ch...
  function map_collect (line 123) | fn map_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[usi...

FILE: src/using/computational_variants/tests/iter_ref.rs
  function input (line 12) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 17) | fn expected(input: &impl Collection<Item = String>, map: impl Fn(String)...
  function empty_collect_into (line 24) | fn empty_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function empty_collect (line 66) | fn empty_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect_into (line 110) | fn map_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect (line 131) | fn map_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/map/collect.rs
  constant N (line 14) | const N: [usize; 2] = [37, 125];
  constant N (line 16) | const N: [usize; 2] = [1025, 4735];
  function m_map_collect (line 24) | fn m_map_collect(n: usize, nt: usize, chunk: usize, ordering: IterationO...

FILE: src/using/computational_variants/tests/map/find.rs
  constant N (line 13) | const N: [usize; 2] = [37, 125];
  constant N (line 15) | const N: [usize; 2] = [1025, 4735];
  function m_find (line 22) | fn m_find(n: usize, nt: usize, chunk: usize) {
  function m_map_find (line 46) | fn m_map_find(n: usize, nt: usize, chunk: usize) {

FILE: src/using/computational_variants/tests/map/reduce.rs
  constant N (line 13) | const N: [usize; 2] = [37, 125];
  constant N (line 15) | const N: [usize; 2] = [1025, 4735];
  function m_reduce (line 22) | fn m_reduce(n: usize, nt: usize, chunk: usize) {
  function m_map_reduce (line 50) | fn m_map_reduce(n: usize, nt: usize, chunk: usize) {

FILE: src/using/computational_variants/tests/min_max.rs
  function input (line 8) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function cmp (line 13) | fn cmp(a: &usize, b: &usize) -> Ordering {
  function key (line 20) | fn key(a: &usize) -> u64 {
  function min_max_empty (line 25) | fn min_max_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_map (line 55) | fn min_max_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_flat_map (line 88) | fn min_max_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_filter_map (line 131) | fn min_max_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function min_max_xap_filter_xap (line 179) | fn min_max_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/range.rs
  constant N_OFFSET (line 11) | const N_OFFSET: usize = 13;
  function offset (line 13) | fn offset() -> Vec<usize> {
  function expected (line 17) | fn expected<T>(
  function empty_collect_into (line 38) | fn empty_collect_into<C>(output: C, n: &[usize], nt: &[usize], chunk: &[...
  function empty_collect (line 60) | fn empty_collect<C>(_: C, n: &[usize], nt: &[usize], chunk: &[usize])
  function map_collect_into (line 84) | fn map_collect_into<C>(output: C, n: &[usize], nt: &[usize], chunk: &[us...
  function map_collect (line 107) | fn map_collect<C>(_: C, n: &[usize], nt: &[usize], chunk: &[usize])

FILE: src/using/computational_variants/tests/slice.rs
  function input (line 12) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 17) | fn expected(input: &impl Collection<Item = String>, map: impl Fn(String)...
  function empty_collect_into (line 24) | fn empty_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function empty_collect (line 66) | fn empty_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect_into (line 110) | fn map_collect_into(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function map_collect (line 131) | fn map_collect(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/sum.rs
  function input (line 7) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function sum_empty (line 13) | fn sum_empty(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_map (line 29) | fn sum_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_flat_map (line 47) | fn sum_xap_flat_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_filter_map (line 65) | fn sum_xap_filter_map(n: &[usize], nt: &[usize], chunk: &[usize]) {
  function sum_xap_filter_xap (line 83) | fn sum_xap_filter_xap(n: &[usize], nt: &[usize], chunk: &[usize]) {

FILE: src/using/computational_variants/tests/utils.rs
  function make_u_map (line 3) | pub(super) fn make_u_map<I, O>(
  function make_u_xap (line 15) | pub(super) fn make_u_xap<I, O>(
  function make_u_filter (line 29) | pub(super) fn make_u_filter<I>(
  function make_u_reduce (line 41) | pub(super) fn make_u_reduce<I>(

FILE: src/using/computational_variants/tests/vectors.rs
  constant N_OFFSET (line 12) | const N_OFFSET: usize = 13;
  function offset (line 14) | fn offset() -> Vec<String> {
  function input (line 18) | fn input<O: FromIterator<String>>(n: usize) -> O {
  function expected (line 23) | fn expected(
  function empty_collect_into (line 45) | fn empty_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ...
  function empty_collect (line 69) | fn empty_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[u...
  function map_collect_into (line 95) | fn map_collect_into<I, C>(_: I, output: C, n: &[usize], nt: &[usize], ch...
  function map_collect (line 120) | fn map_collect<I, C>(_: I, _: C, n: &[usize], nt: &[usize], chunk: &[usi...

FILE: src/using/computational_variants/tests/xap/collect.rs
  constant N (line 17) | const N: [usize; 2] = [37, 125];
  constant N (line 19) | const N: [usize; 2] = [1025, 4735];
  function todo_panic_at_con_bag_new (line 22) | fn todo_panic_at_con_bag_new() {
  function x_flat_map_collect (line 73) | fn x_flat_map_collect(n: usize, nt: usize, chunk: usize, ordering: Itera...
  function x_filter_map_collect (line 118) | fn x_filter_map_collect(n: usize, nt: usize, chunk: usize, ordering: Ite...

FILE: src/using/computational_variants/tests/xap/find.rs
  constant N (line 15) | const N: [usize; 2] = [37, 125];
  constant N (line 17) | const N: [usize; 2] = [1025, 4735];
  function x_flat_map_find (line 24) | fn x_flat_map_find(n: usize, nt: usize, chunk: usize) {
  function x_filter_map_find (line 51) | fn x_filter_map_find(n: usize, nt: usize, chunk: usize) {

FILE: src/using/computational_variants/tests/xap/reduce.rs
  constant N (line 16) | const N: [usize; 2] = [37, 125];
  constant N (line 18) | const N: [usize; 2] = [1025, 4735];
  function x_flat_map_reduce (line 25) | fn x_flat_map_reduce(n: usize, nt: usize, chunk: usize) {
  function x_filter_map_reduce (line 56) | fn x_filter_map_reduce(n: usize, nt: usize, chunk: usize) {

FILE: src/using/computational_variants/u_fallible_option.rs
  type UParOption (line 11) | pub struct UParOption<'using, U, F, T, R = DefaultRunner>
  function new (line 27) | pub(crate) fn new(par: F) -> Self {
  type Item (line 41) | type Item = T;
  function num_threads (line 45) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 49) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 53) | fn iteration_order(self, order: IterationOrder) -> Self {
  function with_runner (line 57) | fn with_runner<Q: ParallelRunner>(
  function map (line 66) | fn map<Out, Map>(self, map: Map) -> impl ParIterOptionUsing<'using, U, R...
  function filter (line 74) | fn filter<Filter>(
  function flat_map (line 86) | fn flat_map<IOut, FlatMap>(
  function filter_map (line 99) | fn filter_map<Out, FilterMap>(
  function inspect (line 111) | fn inspect<Operation>(
  function collect_into (line 125) | fn collect_into<C>(self, output: C) -> Option<C>
  function collect (line 133) | fn collect<C>(self) -> Option<C>
  function reduce (line 143) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Option<Self::Item>>
  function first (line 153) | fn first(self) -> Option<Option<Self::Item>>

FILE: src/using/computational_variants/u_fallible_result/u_map_result.rs
  type UParMapResult (line 11) | pub struct UParMapResult<'using, U, I, T, E, O, M1, R = DefaultRunner>
  function new (line 31) | pub(crate) fn new(par: UParMap<'using, U, I, O, M1, R>) -> Self {
  type Item (line 48) | type Item = T;
  type Err (line 50) | type Err = E;
  type RegularItem (line 52) | type RegularItem = O;
  type RegularParIter (line 54) | type RegularParIter = UParMap<'using, U, I, O, M1, R>;
  function con_iter_len (line 56) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 60) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 64) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 73) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 86) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 103) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 125) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/using/computational_variants/u_fallible_result/u_par_result.rs
  type UParResult (line 11) | pub struct UParResult<'using, U, I, T, E, R = DefaultRunner>
  function new (line 29) | pub(crate) fn new(par: UPar<'using, U, I, R>) -> Self {
  type Item (line 44) | type Item = T;
  type Err (line 46) | type Err = E;
  type RegularItem (line 48) | type RegularItem = I::Item;
  type RegularParIter (line 50) | type RegularParIter = UPar<'using, U, I, R>;
  function con_iter_len (line 52) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 56) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 60) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 69) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 82) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 95) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 113) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/using/computational_variants/u_fallible_result/u_xap_result.rs
  type UParXapResult (line 13) | pub struct UParXapResult<'using, U, I, T, E, Vo, X1, R = DefaultRunner>
  function new (line 39) | pub(crate) fn new(using: U, orchestrator: R, params: Params, iter: I, xa...
  function destruct (line 50) | fn destruct(self) -> (U, R, Params, I, X1) {
  type Item (line 71) | type Item = T;
  type Err (line 73) | type Err = E;
  type RegularItem (line 75) | type RegularItem = Vo::Item;
  type RegularParIter (line 77) | type RegularParIter = UParXap<'using, U, I, Vo, X1, R>;
  function con_iter_len (line 79) | fn con_iter_len(&self) -> Option<usize> {
  function into_regular_par (line 83) | fn into_regular_par(self) -> Self::RegularParIter {
  function from_regular_par (line 88) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self {
  function with_runner (line 95) | fn with_runner<Q: ParallelRunner>(
  function collect_into (line 105) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
  function reduce (line 118) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, Se...
  function first (line 136) | fn first(self) -> Result<Option<Self::Item>, Self::Err>

FILE: src/using/computational_variants/u_map.rs
  type UParMap (line 16) | pub struct UParMap<'using, U, I, O, M1, R = DefaultRunner>
  function new (line 38) | pub(crate) fn new(using: U, orchestrator: R, params: Params, iter: I, ma...
  function destruct (line 49) | pub(crate) fn destruct(self) -> (U, R, Params, I, M1) {
  type Item (line 85) | type Item = O;
  function con_iter (line 87) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 91) | fn params(&self) -> Params {
  function num_threads (line 95) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 100) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 105) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 110) | fn with_runner<Q: ParallelRunner>(
  function map (line 118) | fn map<Out, Map>(self, map: Map) -> impl ParIterUsing<'using, U, R, Item...
  function filter (line 130) | fn filter<Filter>(self, filter: Filter) -> impl ParIterUsing<'using, U, ...
  function flat_map (line 145) | fn flat_map<IOut, FlatMap>(
  function filter_map (line 163) | fn filter_map<Out, FilterMap>(
  function into_fallible_result (line 180) | fn into_fallible_result<Out, Err>(
  function collect_into (line 189) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 197) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 206) | fn first(self) -> Option<Self::Item>

FILE: src/using/computational_variants/u_par.rs
  type UPar (line 18) | pub struct UPar<'using, U, I, R = DefaultRunner>
  function new (line 37) | pub(crate) fn new(using: U, orchestrator: R, params: Params, iter: I) ->...
  function destruct (line 47) | pub(crate) fn destruct(self) -> (U, R, Params, I) {
  type Item (line 74) | type Item = I::Item;
  function con_iter (line 76) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 80) | fn params(&self) -> Params {
  function num_threads (line 84) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 89) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 94) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 99) | fn with_runner<Q: ParallelRunner>(
  function map (line 107) | fn map<Out, Map>(self, map: Map) -> impl ParIterUsing<'using, U, R, Item...
  function filter (line 115) | fn filter<Filter>(self, filter: Filter) -> impl ParIterUsing<'using, U, ...
  function flat_map (line 128) | fn flat_map<IOut, FlatMap>(
  function filter_map (line 145) | fn filter_map<Out, FilterMap>(
  function into_fallible_result (line 161) | fn into_fallible_result<Out, Err>(
  function collect_into (line 170) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 178) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 187) | fn first(self) -> Option<Self::Item>

FILE: src/using/computational_variants/u_xap.rs
  type UParXap (line 16) | pub struct UParXap<'using, U, I, Vo, X1, R = DefaultRunner>
  function new (line 40) | pub(crate) fn new(using: U, orchestrator: R, params: Params, iter: I, xa...
  function destruct (line 51) | pub(crate) fn destruct(self) -> (U, R, Params, I, X1) {
  type Item (line 90) | type Item = Vo::Item;
  function con_iter (line 92) | fn con_iter(&self) -> &impl ConcurrentIter {
  function params (line 96) | fn params(&self) -> Params {
  function num_threads (line 100) | fn num_threads(mut self, num_threads: impl Into<NumThreads>) -> Self {
  function chunk_size (line 105) | fn chunk_size(mut self, chunk_size: impl Into<ChunkSize>) -> Self {
  function iteration_order (line 110) | fn iteration_order(mut self, collect: IterationOrder) -> Self {
  function with_runner (line 115) | fn with_runner<Q: ParallelRunner>(
  function map (line 123) | fn map<Out, Map>(self, map: Map) -> impl ParIterUsing<'using, U, R, Item...
  function filter (line 143) | fn filter<Filter>(self, filter: Filter) -> impl ParIterUsing<'using, U, ...
  function flat_map (line 162) | fn flat_map<IOut, FlatMap>(
  function filter_map (line 185) | fn filter_map<Out, FilterMap>(
  function into_fallible_result (line 207) | fn into_fallible_result<Out, Err>(
  function collect_into (line 217) | fn collect_into<C>(self, output: C) -> C
  function reduce (line 225) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
  function first (line 241) | fn first(self) -> Option<Self::Item>

FILE: src/using/executor/parallel_compute/collect_arbitrary.rs
  function m (line 12) | pub fn m<'using, U, C, I, O, M1, P>(
  function x (line 46) | pub fn x<'using, U, C, I, Vo, X1, P>(

FILE: src/using/executor/parallel_compute/collect_ordered.rs
  function m (line 11) | pub fn m<'using, U, C, I, O, M1, P>(
  function x (line 41) | pub fn x<'using, U, C, I, Vo, X1, P>(

FILE: src/using/executor/parallel_compute/next.rs
  function m (line 9) | pub fn m<'using, U, C, I, O, M1>(
  type ResultNext (line 40) | type ResultNext<Vo> = Result<
  function x (line 45) | pub fn x<'using, U, C, I, Vo, X1>(

FILE: src/using/executor/parallel_compute/next_any.rs
  function m (line 9) | pub fn m<'using, U, C, I, O, M1>(
  type ResultNextAny (line 36) | type ResultNextAny<Vo> =
  function x (line 39) | pub fn x<'using, U, C, I, Vo, X1>(

FILE: src/using/executor/parallel_compute/reduce.rs
  function m (line 9) | pub fn m<'using, U, C, I, O, M1, Red>(
  type ResultReduce (line 44) | type ResultReduce<Vo> =
  function x (line 47) | pub fn x<'using, U, C, I, Vo, X1, Red>(

FILE: src/using/executor/thread_compute/collect_arbitrary.rs
  function m (line 11) | pub fn m<U, C, I, O, M1, P>(
  function x (line 59) | pub fn x<U, C, I, Vo, X1, P>(

FILE: src/using/executor/thread_compute/collect_ordered.rs
  function m (line 9) | pub fn m<U, C, I, O, M1, P>(
  function x (line 58) | pub fn x<U, C, I, Vo, X1>(

FILE: src/using/executor/thread_compute/next.rs
  function m (line 8) | pub fn m<U, C, I, O, M1>(
  function x (line 67) | pub fn x<U, C, I, Vo, X1>(

FILE: src/using/executor/thread_compute/next_any.rs
  function m (line 8) | pub fn m<U, C, I, O, M1>(
  function x (line 68) | pub fn x<U, C, I, Vo, X1>(

FILE: src/using/executor/thread_compute/reduce.rs
  function m (line 12) | pub fn m<U, C, I, O, M1, Red>(
  function x (line 84) | pub fn x<U, C, I, Vo, X1, Red>(

FILE: src/using/u_par_iter.rs
  type ParIterUsing (line 18) | pub trait ParIterUsing<'using, U, R = DefaultRunner>: Sized + Send + Sync
    method con_iter (line 27) | fn con_iter(&self) -> &impl ConcurrentIter;
    method params (line 32) | fn params(&self) -> Params;
    method num_threads (line 46) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
    method chunk_size (line 57) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
    method iteration_order (line 62) | fn iteration_order(self, collect: IterationOrder) -> Self;
    method with_runner (line 70) | fn with_runner<Q: ParallelRunner>(
    method with_pool (line 82) | fn with_pool<P: ParThreadPool>(
    method into_fallible_result (line 112) | fn into_fallible_result<T, E>(self) -> impl ParIterResultUsing<'using,...
    method into_fallible_option (line 133) | fn into_fallible_option<T>(self) -> impl ParIterOptionUsing<'using, U,...
    method map (line 152) | fn map<Out, Map>(self, map: Map) -> impl ParIterUsing<'using, U, R, It...
    method filter (line 163) | fn filter<Filter>(self, filter: Filter) -> impl ParIterUsing<'using, U...
    method flat_map (line 174) | fn flat_map<IOut, FlatMap>(
    method filter_map (line 193) | fn filter_map<Out, FilterMap>(
    method inspect (line 207) | fn inspect<Operation>(
    method copied (line 230) | fn copied<'a, T>(self) -> impl ParIterUsing<'using, U, R, Item = T>
    method cloned (line 245) | fn cloned<'a, T>(self) -> impl ParIterUsing<'using, U, R, Item = T>
    method flatten (line 260) | fn flatten(self) -> impl ParIterUsing<'using, U, R, Item = <Self::Item...
    method collect_into (line 277) | fn collect_into<C>(self, output: C) -> C
    method collect (line 288) | fn collect<C>(self) -> C
    method reduce (line 301) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Self::Item>
    method all (line 313) | fn all<Predicate>(self, predicate: Predicate) -> bool
    method any (line 329) | fn any<Predicate>(self, predicate: Predicate) -> bool
    method count (line 340) | fn count(self) -> usize {
    method for_each (line 351) | fn for_each<Operation>(self, operation: Operation)
    method max (line 362) | fn max(self) -> Option<Self::Item>
    method max_by (line 372) | fn max_by<Compare>(self, compare: Compare) -> Option<Self::Item>
    method max_by_key (line 387) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Option<Self::Item>
    method min (line 403) | fn min(self) -> Option<Self::Item>
    method min_by (line 413) | fn min_by<Compare>(self, compare: Compare) -> Option<Self::Item>
    method min_by_key (line 428) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Option<Self::Item>
    method sum (line 444) | fn sum<Out>(self) -> Out
    method first (line 462) | fn first(self) -> Option<Self::Item>
    method find (line 473) | fn find<Predicate>(self, predicate: Predicate) -> Option<Self::Item>

FILE: src/using/u_par_iter_option.rs
  type ParIterOptionUsing (line 17) | pub trait ParIterOptionUsing<'using, U, R = DefaultRunner>
    method num_threads (line 35) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self;
    method chunk_size (line 46) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self;
    method iteration_order (line 51) | fn iteration_order(self, order: IterationOrder) -> Self;
    method with_runner (line 59) | fn with_runner<Q: ParallelRunner>(
    method with_pool (line 71) | fn with_pool<P: ParThreadPool>(
    method map (line 94) | fn map<Out, Map>(self, map: Map) -> impl ParIterOptionUsing<'using, U,...
    method filter (line 110) | fn filter<Filter>(
    method flat_map (line 129) | fn flat_map<IOut, FlatMap>(
    method filter_map (line 150) | fn filter_map<Out, FilterMap>(
    method inspect (line 167) | fn inspect<Operation>(
    method collect_into (line 186) | fn collect_into<C>(self, output: C) -> Option<C>
    method collect (line 206) | fn collect<C>(self) -> Option<C>
    method reduce (line 223) | fn reduce<Reduce>(self, reduce: Reduce) -> Option<Option<Self::Item>>
    method all (line 236) | fn all<Predicate>(self, predicate: Predicate) -> Option<bool>
    method any (line 254) | fn any<Predicate>(self, predicate: Predicate) -> Option<bool>
    method count (line 267) | fn count(self) -> Option<usize>
    method for_each (line 284) | fn for_each<Operation>(self, operation: Operation) -> Option<()>
    method max (line 298) | fn max(self) -> Option<Option<Self::Item>>
    method max_by (line 311) | fn max_by<Compare>(self, compare: Compare) -> Option<Option<Self::Item>>
    method max_by_key (line 329) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Option<Option<Self::I...
    method min (line 348) | fn min(self) -> Option<Option<Self::Item>>
    method min_by (line 361) | fn min_by<Compare>(self, compare: Compare) -> Option<Option<Self::Item>>
    method min_by_key (line 379) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Option<Option<Sel...
    method sum (line 399) | fn sum<Out>(self) -> Option<Out>
    method first (line 420) | fn first(self) -> Option<Option<Self::Item>>
    method find (line 442) | fn find<Predicate>(self, predicate: Predicate) -> Option<Option<Self::...

FILE: src/using/u_par_iter_result.rs
  type ParIterResultUsing (line 19) | pub trait ParIterResultUsing<'using, U, R = DefaultRunner>
    method con_iter_len (line 37) | fn con_iter_len(&self) -> Option<usize>;
    method into_regular_par (line 40) | fn into_regular_par(self) -> Self::RegularParIter;
    method from_regular_par (line 43) | fn from_regular_par(regular_par: Self::RegularParIter) -> Self;
    method num_threads (line 55) | fn num_threads(self, num_threads: impl Into<NumThreads>) -> Self
    method chunk_size (line 71) | fn chunk_size(self, chunk_size: impl Into<ChunkSize>) -> Self
    method iteration_order (line 81) | fn iteration_order(self, order: IterationOrder) -> Self
    method with_runner (line 94) | fn with_runner<Q: ParallelRunner>(
    method with_pool (line 106) | fn with_pool<P: ParThreadPool>(
    method map (line 135) | fn map<Out, Map>(
    method filter (line 159) | fn filter<Filter>(
    method flat_map (line 189) | fn flat_map<IOut, FlatMap>(
    method filter_map (line 219) | fn filter_map<Out, FilterMap>(
    method inspect (line 244) | fn inspect<Operation>(
    method collect_into (line 270) | fn collect_into<C>(self, output: C) -> Result<C, Self::Err>
    method collect (line 291) | fn collect<C>(self) -> Result<C, Self::Err>
    method reduce (line 314) | fn reduce<Reduce>(self, reduce: Reduce) -> Result<Option<Self::Item>, ...
    method all (line 328) | fn all<Predicate>(self, predicate: Predicate) -> Result<bool, Self::Err>
    method any (line 347) | fn any<Predicate>(self, predicate: Predicate) -> Result<bool, Self::Err>
    method count (line 361) | fn count(self) -> Result<usize, Self::Err>
    method for_each (line 379) | fn for_each<Operation>(self, operation: Operation) -> Result<(), Self:...
    method max (line 394) | fn max(self) -> Result<Option<Self::Item>, Self::Err>
    method max_by (line 408) | fn max_by<Compare>(self, compare: Compare) -> Result<Option<Self::Item...
    method max_by_key (line 427) | fn max_by_key<Key, GetKey>(self, key: GetKey) -> Result<Option<Self::I...
    method min (line 447) | fn min(self) -> Result<Option<Self::Item>, Self::Err>
    method min_by (line 461) | fn min_by<Compare>(self, compare: Compare) -> Result<Option<Self::Item...
    method min_by_key (line 480) | fn min_by_key<Key, GetKey>(self, get_key: GetKey) -> Result<Option<Sel...
    method sum (line 501) | fn sum<Out>(self) -> Result<Out, Self::Err>
    method first (line 523) | fn first(self) -> Result<Option<Self::Item>, Self::Err>
    method find (line 546) | fn find<Predicate>(self, predicate: Predicate) -> Result<Option<Self::...

FILE: src/using/using_variants.rs
  type Using (line 5) | pub trait Using<'using>: Sync {
    method create (line 10) | fn create(&self, thread_idx: usize) -> Self::Item;
    method into_inner (line 13) | fn into_inner(self) -> Self::Item;
  type UsingClone (line 17) | pub struct UsingClone<T: Clone + 'static>(T);
  function new (line 20) | pub(crate) fn new(value: T) -> Self {
  type Item (line 26) | type Item = T;
  function create (line 28) | fn create(&self, _: usize) -> T {
  function into_inner (line 32) | fn into_inner(self) -> Self::Item {
  type UsingFun (line 40) | pub struct UsingFun<F, T>
  function new (line 51) | pub(crate) fn new(fun: F) -> Self {
  type Item (line 61) | type Item = T;
  function create (line 63) | fn create(&self, thread_idx: usize) -> Self::Item {
  function into_inner (line 67) | fn into_inner(self) -> Self::Item {

FILE: src/value_variants/whilst_iterators/whilst_atom_flat_map.rs
  type WhilstAtomFlatMapIter (line 3) | pub struct WhilstAtomFlatMapIter<Vo>
  function from_atom (line 14) | pub fn from_atom<T, Fm>(atom: WhilstAtom<T>, flat_map: Fm) -> Self
  function u_from_atom (line 25) | pub fn u_from_atom<U, T, Fm>(u: &mut U, atom: WhilstAtom<T>, flat_map: F...
  type Item (line 41) | type Item = WhilstAtom<Vo::Item>;
  method next (line 43) | fn next(&mut self) -> Option<Self::Item> {

FILE: src/value_variants/whilst_iterators/whilst_option_flat_map.rs
  type WhilstOptionFlatMapIter (line 3) | pub struct WhilstOptionFlatMapIter<Vo>
  function from_option (line 14) | pub fn from_option<T, Fm>(atom: WhilstOption<T>, flat_map: Fm) -> Self
  function u_from_option (line 26) | pub fn u_from_option<U, T, Fm>(u: &mut U, atom: WhilstOption<T>, flat_ma...
  type Item (line 43) | type Item = WhilstAtom<Vo::Item>;
  method next (line 45) | fn next(&mut self) -> Option<Self::Item> {

FILE: src/value_variants/whilst_vector.rs
  type WhilstVector (line 14) | pub struct WhilstVector<I, T>(pub(crate) I)
  type Item (line 22) | type Item = T;
  type Fallibility (line 24) | type Fallibility = Infallible;
  method push_to_pinned_vec (line 26) | fn push_to_pinned_vec<P>(self, vector: &mut P) -> SequentialPush<Self::F...
  method push_to_vec_with_idx (line 39) | fn push_to_vec_with_idx(
  method push_to_bag (line 53) | fn push_to_bag<P>(self, bag: &ConcurrentBag<Self::Item, P>) -> Arbitrary...
  method acc_reduce (line 67) | fn acc_reduce<X>(self, acc: Option<Self::Item>, reduce: X) -> Reduce<Self>
  method u_acc_reduce (line 97) | fn u_acc_reduce<U, X>(self, u: &mut U, acc: Option<Self::Item>, reduce: ...
  method next (line 127) | fn next(self) -> Next<Self> {
  method map (line 142) | fn map<M, O>(
  method filter (line 156) | fn filter<F>(
  method flat_map (line 173) | fn flat_map<Fm, Vo>(
  method filter_map (line 188) | fn filter_map<Fm, O>(
  method whilst (line 202) | fn whilst(
  method map_while_ok (line 219) | fn map_while_ok<Mr, O, E>(self, map_res: Mr) -> impl Values<Item = O, Fa...
  method u_map (line 231) | fn u_map<U, M, O>(
  method u_filter (line 246) | fn u_filter<U, F>(
  method u_flat_map (line 264) | fn u_flat_map<U, Fm, Vo>(
  method u_filter_map (line 280) | fn u_filter_map<U, Fm, O>(

FILE: tests/chain.rs
  function chain_known_known (line 5) | fn chain_known_known(n: usize, nt: usize, chunk: usize) {
  function chain_known_unknown (line 20) | fn chain_known_unknown(n: usize, nt: usize, chunk: usize) {

FILE: tests/into_par.rs
  function take_into_par_into_par_bounds (line 4) | fn take_into_par_into_par_bounds<T>(a: impl IntoParIter<Item = T>) {
  function take_into_par_into_con_iter_bounds (line 8) | fn take_into_par_into_con_iter_bounds<T>(a: impl IntoConcurrentIter<Item...
  function vec_into_par_iter (line 13) | fn vec_into_par_iter() {
  function slice_into_par_iter (line 22) | fn slice_into_par_iter() {
  function range_into_par_iter (line 32) | fn range_into_par_iter() {

FILE: tests/iter_into_par.rs
  function take_iter_into_par_iterator_bounds (line 4) | fn take_iter_into_par_iterator_bounds<I>(a: I)
  function take_iter_into_par_iter_into_con_iter_bounds (line 12) | fn take_iter_into_par_iter_into_con_iter_bounds<I>(a: I)
  function take_iter_into_par_iter_into_par_bounds (line 20) | fn take_iter_into_par_iter_into_par_bounds<T: Send>(a: impl IterIntoParI...
  function iter_into_par_iter (line 25) | fn iter_into_par_iter() {

FILE: tests/map_while_ok_collect/from_map.rs
  function map_while_ok_from_map_when_ok (line 4) | fn map_while_ok_from_map_when_ok() {
  function map_while_ok_from_map_when_error (line 24) | fn map_while_ok_from_map_when_error() {

FILE: tests/map_while_ok_collect/from_par.rs
  function map_while_ok_from_par_when_ok (line 4) | fn map_while_ok_from_par_when_ok() {
  function map_while_ok_from_par_when_error (line 22) | fn map_while_ok_from_par_when_error() {

FILE: tests/map_while_ok_collect/from_xap_chain.rs
  function map_while_ok_from_xap_chain_when_ok (line 4) | fn map_while_ok_from_xap_chain_when_ok() {
  function map_while_ok_from_xap_chain_when_error (line 38) | fn map_while_ok_from_xap_chain_when_error() {
  function map_while_ok_from_xap_chain_whilst_when_ok (line 72) | fn map_while_ok_from_xap_chain_whilst_when_ok() {
  function map_while_ok_from_xap_chain_whilst_when_err (line 111) | fn map_while_ok_from_xap_chain_whilst_when_err() {
  function map_while_ok_from_xap_chain_whilst_when_err_out_of_reach (line 146) | fn map_while_ok_from_xap_chain_whilst_when_err_out_of_reach() {

FILE: tests/map_while_ok_collect/from_xap_filter.rs
  function map_while_ok_from_xap_filter_when_ok (line 4) | fn map_while_ok_from_xap_filter_when_ok() {
  function map_while_ok_from_xap_filter_when_error (line 24) | fn map_while_ok_from_xap_filter_when_error() {
  function map_while_ok_from_xap_filter_whilst_when_ok (line 49) | fn map_while_ok_from_xap_filter_whilst_when_ok() {
  function map_while_ok_from_xap_filter_whilst_when_err (line 73) | fn map_while_ok_from_xap_filter_whilst_when_err() {
  function map_while_ok_from_xap_filter_whilst_when_err_out_of_reach (line 99) | fn map_while_ok_from_xap_filter_whilst_when_err_out_of_reach() {

FILE: tests/map_while_ok_collect/from_xap_filter_map.rs
  function map_while_ok_from_xap_filter_map_when_ok (line 4) | fn map_while_ok_from_xap_filter_map_when_ok() {
  function map_while_ok_from_xap_filter_map_when_error (line 24) | fn map_while_ok_from_xap_filter_map_when_error() {
  function map_while_ok_from_xap_filter_map_whilst_when_ok (line 49) | fn map_while_ok_from_xap_filter_map_whilst_when_ok() {
  function map_while_ok_from_xap_filter_map_whilst_when_error (line 73) | fn map_while_ok_from_xap_filter_map_whilst_when_error() {
  function map_while_ok_from_xap_filter_map_whilst_when_error_out_of_reach (line 99) | fn map_while_ok_from_xap_filter_map_whilst_when_error_out_of_reach() {

FILE: tests/map_while_ok_collect/from_xap_flat_map.rs
  function map_while_ok_from_xap_flat_map_when_ok (line 4) | fn map_while_ok_from_xap_flat_map_when_ok() {
  function map_while_ok_from_xap_flat_map_when_error (line 24) | fn map_while_ok_from_xap_flat_map_when_error() {
  function map_while_ok_from_xap_flat_map_whilst_when_ok (line 49) | fn map_while_ok_from_xap_flat_map_whilst_when_ok() {
  function map_while_ok_from_xap_flat_map_whilst_when_error (line 75) | fn map_while_ok_from_xap_flat_map_whilst_when_error() {
  function map_while_ok_from_xap_flat_map_whilst_when_error_out_of_reach (line 101) | fn map_while_ok_from_xap_flat_map_whilst_when_error_out_of_reach() {

FILE: tests/map_while_ok_collect_arbitrary/from_map.rs
  function map_while_ok_from_map_when_ok (line 6) | fn map_while_ok_from_map_when_ok() {
  function map_while_ok_from_map_when_error (line 28) | fn map_while_ok_from_map_when_error() {

FILE: tests/map_while_ok_collect_arbitrary/from_par.rs
  function map_while_ok_from_par_when_ok (line 6) | fn map_while_ok_from_par_when_ok() {
  function map_while_ok_from_par_when_error (line 26) | fn map_while_ok_from_par_when_error() {

FILE: tests/map_while_ok_collect_arbitrary/from_xap_chain.rs
  function map_while_ok_from_xap_chain_when_ok (line 5) | fn map_while_ok_from_xap_chain_when_ok() {
  function map_while_ok_from_xap_chain_when_error (line 43) | fn map_while_ok_from_xap_chain_when_error() {
  function map_while_ok_from_xap_chain_whilst_when_ok (line 78) | fn map_while_ok_from_xap_chain_whilst_when_ok() {
  function map_while_ok_from_xap_chain_whilst_when_err (line 111) | fn map_while_ok_from_xap_chain_whilst_when_err() {
  function map_while_ok_from_xap_chain_whilst_when_err_out_of_reach (line 147) | fn map_while_ok_from_xap_chain_whilst_when_err_out_of_reach() {

FILE: tests/map_while_ok_collect_arbitrary/from_xap_filter.rs
  function map_while_ok_from_xap_filter_when_ok (line 5) | fn map_while_ok_from_xap_filter_when_ok() {
  function map_while_ok_from_xap_filter_when_error (line 28) | fn map_while_ok_from_xap_filter_when_error() {
  function map_while_ok_from_xap_filter_whilst_when_ok (line 54) | fn map_while_ok_from_xap_filter_whilst_when_ok() {
  function map_while_ok_from_xap_filter_whilst_when_err (line 78) | fn map_while_ok_from_xap_filter_whilst_when_err() {
  function map_while_ok_from_xap_filter_whilst_when_err_out_of_reach (line 105) | fn map_while_ok_from_xap_filter_whilst_when_err_out_of_reach() {

FILE: tests/map_while_ok_collect_arbitrary/from_xap_filter_map.rs
  function map_while_ok_from_xap_filter_map_when_ok (line 5) | fn map_while_ok_from_xap_filter_map_when_ok() {
  function map_while_ok_from_xap_filter_map_when_error (line 28) | fn map_while_ok_from_xap_filter_map_when_error() {
  function map_while_ok_from_xap_filter_map_whilst_when_ok (line 54) | fn map_while_ok_from_xap_filter_map_whilst_when_ok() {
  function map_while_ok_from_xap_filter_map_whilst_when_error (line 78) | fn map_while_ok_from_xap_filter_map_whilst_when_error() {
  function map_while_ok_from_xap_filter_map_whilst_when_error_out_of_reach (line 105) | fn map_while_ok_from_xap_filter_map_whilst_when_error_out_of_reach() {

FILE: tests/map_while_ok_collect_arbitrary/from_xap_flat_map.rs
  function map_while_ok_from_xap_flat_map_when_ok (line 6) | fn map_while_ok_from_xap_flat_map_when_ok() {
  function map_while_ok_from_xap_flat_map_when_error (line 30) | fn map_while_ok_from_xap_flat_map_when_error() {
  function map_while_ok_from_xap_flat_map_whilst_when_ok (line 56) | fn map_while_ok_from_xap_flat_map_whilst_when_ok() {
  function map_while_ok_from_xap_flat_map_whilst_when_error (line 81) | fn map_while_ok_from_xap_flat_map_whilst_when_error() {
  function map_while_ok_from_xap_flat_map_whilst_when_error_out_of_reach (line 108) | fn map_while_ok_from_xap_flat_map_whilst_when_error_out_of_reach() {

FILE: tests/map_while_ok_collect_arbitrary/utils.rs
  function sort_if_ok (line 1) | pub fn sort_if_ok<T: Ord + PartialOrd, E>(res_vec: Result<Vec<T>, E>) ->...

FILE: tests/map_while_ok_reduce/from_map.rs
  function map_while_ok_from_map_when_ok (line 4) | fn map_while_ok_from_map_when_ok() {
  function map_while_ok_from_map_when_error (line 32) | fn map_while_ok_from_map_when_error() {

FILE: tests/map_while_ok_reduce/from_par.rs
  function map_while_ok_from_par_when_ok (line 4) | fn map_while_ok_from_par_when_ok() {
  function map_while_ok_from_par_when_error (line 22) | fn map_while_ok_from_par_when_error() {

FILE: tests/map_while_ok_reduce/from_xap_chain.rs
  function map_while_ok_from_xap_chain_when_ok (line 4) | fn map_while_ok_from_xap_chain_when_ok() {
  function map_while_ok_from_xap_chain_when_error (line 38) | fn map_while_ok_from_xap_chain_when_error() {

FILE: tests/map_while_ok_reduce/from_xap_filter.rs
  function map_while_ok_from_xap_filter_when_ok (line 4) | fn map_while_ok_from_xap_filter_when_ok() {
  function map_while_ok_from_xap_filter_when_ok_but_none (line 24) | fn map_while_ok_from_xap_filter_when_ok_but_none() {
  function map_while_ok_from_xap_filter_when_error (line 44) | fn map_while_ok_from_xap_filter_when_error() {

FILE: tests/map_while_ok_reduce/from_xap_filter_map.rs
  function map_while_ok_from_xap_filter_map_when_ok (line 4) | fn map_while_ok_from_xap_filter_map_when_ok() {
  function map_while_ok_from_xap_filter_map_when_ok_but_none (line 24) | fn map_while_ok_from_xap_filter_map_when_ok_but_none() {
  function map_while_ok_from_xap_filter_map_when_error (line 44) | fn map_while_ok_from_xap_filter_map_when_error() {

FILE: tests/map_while_ok_reduce/from_xap_flat_map.rs
  function map_while_ok_from_xap_flat_map_when_ok (line 4) | fn map_while_ok_from_xap_flat_map_when_ok() {
  function map_while_ok_from_xap_flat_map_when_ok_but_none (line 24) | fn map_while_ok_from_xap_flat_map_when_ok_but_none() {
  function map_while_ok_from_xap_flat_map_when_error (line 44) | fn map_while_ok_from_xap_flat_map_when_error() {

FILE: tests/mut_iter.rs
  constant N (line 7) | const N: [usize; 2] = [37, 125];
  constant N (line 9) | const N: [usize; 2] = [1025, 4735];
  type Data (line 12) | struct Data {
  function to_output (line 17) | fn to_output(idx: usize) -> Data {
  function filter (line 23) | fn filter(data: &&mut Data) -> bool {
  function update (line 27) | fn update(data: &mut Data) {
  function mut_iter (line 39) | fn mut_iter(n: usize, nt: usize, chunk: usize) {
  function mut_slice (line 61) | fn mut_slice(n: usize, nt: usize, chunk: usize) {

FILE: tests/parallel_drainable.rs
  type VecAndRange (line 6) | struct VecAndRange(Vec<String>, Range<usize>);
    method new (line 9) | fn new(n: usize) -> VecAndRange {
  function parallel_drainable_vec (line 30) | fn parallel_drainable_vec(n: usize, nt: usize, chunk: usize) {

FILE: tests/parallelizable.rs
  function take_parallelizable (line 4) | fn take_parallelizable<T>(a: impl Parallelizable<Item = T>) {
  function vec_parallelizable (line 10) | fn vec_parallelizable() {
  function slice_parallelizable (line 16) | fn slice_parallelizable() {
  function range_parallelizable (line 23) | fn range_parallelizable() {
  function cloning_iter_parallelizable (line 29) | fn cloning_iter_parallelizable() {

FILE: tests/parallelizable_collection.rs
  function take_parallelizable_collection (line 3) | fn take_parallelizable_collection<T>(a: impl ParallelizableCollection<It...
  function vec_parallelizable_collection (line 9) | fn vec_parallelizable_collection() {

FILE: tests/test_groups.rs
  function fibonacci (line 7) | pub fn fibonacci(n: u64) -> u64 {

FILE: tests/trait_bounds.rs
  function trait_bounds_parallelizable (line 6) | fn trait_bounds_parallelizable() {
  function trait_bounds_parallelizable_collection (line 21) | fn trait_bounds_parallelizable_collection() {
  function trait_bounds_into_par_iter (line 34) | fn trait_bounds_into_par_iter() {

FILE: tests/using/rng.rs
  function random_walk (line 5) | fn random_walk(rng: &mut impl Rng, position: i64, num_steps: usize) -> i...
  function random_step (line 9) | fn random_step(rng: &mut impl Rng, position: i64) -> i64 {
  function input_positions (line 16) | fn input_positions() -> Vec<i64> {
  function using_rng_map (line 21) | fn using_rng_map() {
  function using_rng_xap (line 35) | fn using_rng_xap() {
  function using_rng_xap_long (line 51) | fn using_rng_xap_long() {

FILE: tests/whilst/collect.rs
  function par (line 11) | fn par(n: usize, nt: usize, c: usize, until_num_digits: usize, until_dig...
  function map (line 35) | fn map(n: usize, nt: usize, c: usize, until_num_digits: usize, until_dig...
  function xap_filter (line 59) | fn xap_filter(n: usize, nt: usize, c: usize, stop_at: &[&str], filter_ou...
  function xap_filter_map (line 84) | fn xap_filter_map(n: usize, nt: usize, c: usize, stop_at: &[&str], filte...
  function xap_flat_map (line 109) | fn xap_flat_map(n: usize, nt: usize, c: usize, stop_at: &[usize], stop_a...

FILE: tests/whilst/collect_arbitrary.rs
  function par (line 10) | fn par(n: usize, nt: usize, c: usize, until_num_digits: usize, until_dig...
  function map (line 34) | fn map(n: usize, nt: usize, c: usize, until_num_digits: usize, until_dig...
  function xap_filter (line 59) | fn xap_filter(
  function xap_filter_map (line 91) | fn xap_filter_map(
  function xap_flat_map (line 123) | fn xap_flat_map(

FILE: tests/whilst/find.rs
  function par (line 10) | fn par(n: usize, nt: usize, c: usize, stop_at: &[usize], find: &[usize],...
  function filter (line 33) | fn filter(
  function flat_map (line 64) | fn flat_map(

FILE: tests/whilst/reduce.rs
  function par (line 10) | fn par(n: usize, nt: usize, c: usize, stop_at: usize, expected_min: usiz...
  function www_map (line 29) | fn www_map(n: usize, nt: usize, c: usize, stop_at: usize, expected_min: ...
  function filter (line 51) | fn filter(n: usize, nt: usize, c: usize, stop_at: usize, expected_min: u...
  function flatmap (line 71) | fn flatmap(n: usize, nt: usize, c: usize, stop_at: usize, expected_min: ...
Condensed preview — 341 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,248K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 17,
    "preview": "github: [orxfun]\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2938,
    "preview": "# Updated workflow (based on .github/workflows/ci.yml at ref d04ad7abce0c67776a7189001f706535e3e5c402)\nname: Rust\n\non:\n "
  },
  {
    "path": ".gitignore",
    "chars": 446,
    "preview": "# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n.vscode/\n\n# Remove Cargo.lock from gitign"
  },
  {
    "path": ".scripts/run_benchmark.sh",
    "chars": 231,
    "preview": "original_bench=find_iter_into_par\nbench=$1\n\nsed -i \"s/$original_bench/$bench/g\" Cargo.toml\n\nrm -f benches/results/$bench"
  },
  {
    "path": ".scripts/run_benchmarks.sh",
    "chars": 972,
    "preview": "allBenches=(\n    chain_collect_map\n    chain3_collect_map\n    chain4_collect_map\n    collect_filter\n    collect_filterma"
  },
  {
    "path": "Cargo.toml",
    "chars": 2392,
    "preview": "[package]\nname = \"orx-parallel\"\nversion = \"3.4.0\"\nedition = \"2024\"\nauthors = [\"orxfun <orx.ugur.arikan@gmail.com>\"]\nread"
  },
  {
    "path": "LICENSE-APACHE",
    "chars": 9723,
    "preview": "                              Apache License\n                        Version 2.0, January 2004\n                     http"
  },
  {
    "path": "LICENSE-MIT",
    "chars": 1068,
    "preview": "MIT License\n\nCopyright (c) 2024 Ugur Arikan\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
  },
  {
    "path": "README.md",
    "chars": 37947,
    "preview": "# orx-parallel\n\n[![orx-parallel crate](https://img.shields.io/crates/v/orx-parallel.svg)](https://crates.io/crates/orx-p"
  },
  {
    "path": "benches/chain3_collect_map.rs",
    "chars": 3264,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/chain4_collect_map.rs",
    "chars": 3401,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/chain_collect_map.rs",
    "chars": 3072,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_filter.rs",
    "chars": 5410,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_filtermap.rs",
    "chars": 3168,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_flatmap.rs",
    "chars": 3170,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_iter_into_par.rs",
    "chars": 3414,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_long_chain.rs",
    "chars": 4447,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_map.rs",
    "chars": 3010,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_map_filter.rs",
    "chars": 5615,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/collect_map_filter_hash_set.rs",
    "chars": 3408,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/count_filtermap.rs",
    "chars": 2664,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/count_flatmap.rs",
    "chars": 2656,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/count_map.rs",
    "chars": 2510,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/count_map_filter.rs",
    "chars": 2743,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/drain_vec_collect_map_filter.rs",
    "chars": 3344,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/find.rs",
    "chars": 3437,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/find_any.rs",
    "chars": 3509,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/find_flatmap.rs",
    "chars": 3564,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/find_iter_into_par.rs",
    "chars": 3620,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/find_map_filter.rs",
    "chars": 3553,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/mut_for_each_iter.rs",
    "chars": 2396,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse std::collections::HashMap;\n\n#[derive(Debug"
  },
  {
    "path": "benches/mut_for_each_slice.rs",
    "chars": 2243,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse std::hint::black_box;\n\n#[derive(Debug, Par"
  },
  {
    "path": "benches/rec_iter_map_collect.rs",
    "chars": 4652,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_concurrent_recursive_iter::Queue;\nuse "
  },
  {
    "path": "benches/rec_iter_map_sum.rs",
    "chars": 5919,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_concurrent_recursive_iter::Queue;\nuse "
  },
  {
    "path": "benches/reduce.rs",
    "chars": 2714,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/reduce_iter_into_par.rs",
    "chars": 4953,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/reduce_long_chain.rs",
    "chars": 4186,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/reduce_map.rs",
    "chars": 2684,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/reduce_map_filter.rs",
    "chars": 2834,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/result_collect_map.rs",
    "chars": 4704,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse rand::prelude::*;\nuse rand_chacha::ChaCha8"
  },
  {
    "path": "benches/result_reduce_map.rs",
    "chars": 5599,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_concurrent_option::{ConcurrentOption, "
  },
  {
    "path": "benches/sum.rs",
    "chars": 1802,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/sum_filtermap.rs",
    "chars": 2694,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/sum_flatmap.rs",
    "chars": 2696,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/sum_map_filter.rs",
    "chars": 1922,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse rand::prelude::*;\nuse"
  },
  {
    "path": "benches/t_par_merge_sorted.rs",
    "chars": 9546,
    "preview": "use criterion::{Criterion, criterion_group, criterion_main};\n\n#[cfg(feature = \"experiment\")]\nmod inner {\n    use criteri"
  },
  {
    "path": "benches/t_seq_merge_sorted.rs",
    "chars": 7665,
    "preview": "use criterion::{Criterion, criterion_group, criterion_main};\n\n#[cfg(feature = \"experiment\")]\nmod inner {\n    use criteri"
  },
  {
    "path": "benches/vec_deque_collect_map_filter.rs",
    "chars": 3338,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "benches/vec_deque_collect_map_filter_owned.rs",
    "chars": 3372,
    "preview": "use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};\nuse orx_parallel::*;\nuse orx_split_vec::SplitV"
  },
  {
    "path": "docs/using.md",
    "chars": 14740,
    "preview": "# Using Transformation\n\n[`ParIter`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html) trait is design"
  },
  {
    "path": "examples/benchmark_collect.rs",
    "chars": 2513,
    "preview": "mod utils;\n\n#[cfg(not(feature = \"generic_iterator\"))]\nfn main() {\n    panic!(\n        r#\"\n\nREQUIRES FEATURE: generic_ite"
  },
  {
    "path": "examples/benchmark_find.rs",
    "chars": 4069,
    "preview": "mod utils;\n\n#[cfg(not(feature = \"generic_iterator\"))]\nfn main() {\n    panic!(\n        r#\"\n\nREQUIRES FEATURE: generic_ite"
  },
  {
    "path": "examples/benchmark_find_any.rs",
    "chars": 4012,
    "preview": "mod utils;\n\n#[cfg(not(feature = \"generic_iterator\"))]\nfn main() {\n    panic!(\n        r#\"\n\nREQUIRES FEATURE: generic_ite"
  },
  {
    "path": "examples/benchmark_heterogeneous.rs",
    "chars": 2902,
    "preview": "mod utils;\n\n#[cfg(not(feature = \"generic_iterator\"))]\nfn main() {\n    panic!(\n        r#\"\n\nREQUIRES FEATURE: generic_ite"
  },
  {
    "path": "examples/benchmark_pools.rs",
    "chars": 9696,
    "preview": "// cargo run --all-features --release --example benchmark_pools\n// to run with all options:\n//\n// output:\n//\n// Args { p"
  },
  {
    "path": "examples/benchmark_reduce.rs",
    "chars": 2619,
    "preview": "mod utils;\n\n#[cfg(not(feature = \"generic_iterator\"))]\nfn main() {\n    panic!(\n        r#\"\n\nREQUIRES FEATURE: generic_ite"
  },
  {
    "path": "examples/collection_of_results.rs",
    "chars": 3682,
    "preview": "use orx_concurrent_option::ConcurrentOption;\nuse orx_parallel::*;\n\nconst N: usize = 10_000;\nconst IDX_BAD_INPUT: [usize;"
  },
  {
    "path": "examples/function_composition_with_mut_using.rs",
    "chars": 9438,
    "preview": "use clap::Parser;\nuse core::cell::UnsafeCell;\n\n/*\nThis example demonstrates potential issues found by miri with differen"
  },
  {
    "path": "examples/map_while.rs",
    "chars": 783,
    "preview": "use orx_parallel::*;\n\nconst N: usize = 10_000;\nconst IDX_BAD_INPUT: [usize; 4] = [1900, 4156, 6777, 5663];\n\nfn good_inpu"
  },
  {
    "path": "examples/max_num_threads_config.rs",
    "chars": 1645,
    "preview": "/*\n1. to run the computation without any limits on max number of threads:\ncargo run --release --example max_num_threads_"
  },
  {
    "path": "examples/mutable_par_iter.rs",
    "chars": 2120,
    "preview": "use orx_parallel::{\n    IntoParIter, IterIntoParIter, ParIter, ParallelizableCollection, ParallelizableCollectionMut,\n};"
  },
  {
    "path": "examples/par_merge_sorted.rs",
    "chars": 4411,
    "preview": "#[cfg(not(feature = \"experiment\"))]\nfn main() {\n    panic!(\"REQUIRES FEATURE: experiment\");\n}\n\n#[cfg(feature = \"experime"
  },
  {
    "path": "examples/parallelization_on_tree/collection_on_entire_tree.rs",
    "chars": 3810,
    "preview": "use crate::run_utils::timed;\nuse orx_parallel::*;\n\ntype Node = crate::node::Node<String>;\n\npub fn run(root: &Node) {\n   "
  },
  {
    "path": "examples/parallelization_on_tree/main.rs",
    "chars": 1360,
    "preview": "use crate::tree::Tree;\nuse clap::Parser;\nuse rand::SeedableRng;\nuse rand_chacha::ChaCha8Rng;\nuse std::sync::OnceLock;\n\nm"
  },
  {
    "path": "examples/parallelization_on_tree/node.rs",
    "chars": 820,
    "preview": "use std::fmt::Debug;\n\npub struct Node<T> {\n    pub idx: usize,\n    pub data: T,\n    pub children: Vec<Node<T>>,\n}\n\nimpl<"
  },
  {
    "path": "examples/parallelization_on_tree/reduction_on_entire_tree.rs",
    "chars": 4987,
    "preview": "use crate::run_utils::timed;\nuse orx_parallel::*;\nuse std::sync::atomic::{AtomicU64, Ordering};\n\ntype Node = crate::node"
  },
  {
    "path": "examples/parallelization_on_tree/reduction_on_subset_of_tree.rs",
    "chars": 3497,
    "preview": "use crate::run_utils::timed;\nuse orx_parallel::*;\n\ntype Node = crate::node::Node<String>;\n\npub fn run(root: &Node) {\n   "
  },
  {
    "path": "examples/parallelization_on_tree/run_utils.rs",
    "chars": 770,
    "preview": "use crate::amount_of_work;\nuse std::time::Instant;\n\npub fn timed<F, L, T>(name: &'static str, fun: F, log: L)\nwhere\n    "
  },
  {
    "path": "examples/parallelization_on_tree/tree.rs",
    "chars": 1956,
    "preview": "use crate::node::Node;\nuse rand::Rng;\nuse std::{collections::HashSet, marker::PhantomData, ops::Range};\n\npub struct Tree"
  },
  {
    "path": "examples/using_for_each.rs",
    "chars": 1145,
    "preview": "use orx_parallel::*;\nuse std::sync::mpsc::channel;\n\n// taken from rayon's documentation:\n// https://docs.rs/rayon/1.10.0"
  },
  {
    "path": "examples/using_map.rs",
    "chars": 3340,
    "preview": "use orx_parallel::*;\nuse rand::{Rng, SeedableRng};\nuse rand_chacha::ChaCha20Rng;\nuse std::sync::atomic::{AtomicUsize, Or"
  },
  {
    "path": "examples/using_metrics.rs",
    "chars": 3597,
    "preview": "use orx_parallel::*;\nuse std::cell::UnsafeCell;\n\nconst N: u64 = 10_000_000;\nconst MAX_NUM_THREADS: usize = 8;\n\n// just s"
  },
  {
    "path": "examples/using_random_walk.rs",
    "chars": 1663,
    "preview": "use orx_parallel::*;\nuse rand::{Rng, SeedableRng};\nuse rand_chacha::ChaCha20Rng;\n\nfn random_walk(rng: &mut impl Rng, pos"
  },
  {
    "path": "examples/utils/benchmark_utils.rs",
    "chars": 2425,
    "preview": "#![allow(dead_code)]\n\nuse std::{\n    fmt::Debug,\n    hint::black_box,\n    time::{Duration, SystemTime},\n};\n\n// reduce\n\nf"
  },
  {
    "path": "examples/utils/mod.rs",
    "chars": 77,
    "preview": "#![allow(unused_imports)]\n\nmod benchmark_utils;\n\npub use benchmark_utils::*;\n"
  },
  {
    "path": "src/collect_into/collect.rs",
    "chars": 5037,
    "preview": "use crate::Params;\nuse crate::executor::parallel_compute as prc;\nuse crate::generic_values::runner_results::{\n    Fallib"
  },
  {
    "path": "src/collect_into/fixed_vec.rs",
    "chars": 1974,
    "preview": "use super::par_collect_into::ParCollectIntoCore;\nuse crate::Params;\nuse crate::generic_values::runner_results::{Fallibil"
  },
  {
    "path": "src/collect_into/mod.rs",
    "chars": 203,
    "preview": "pub(crate) mod collect;\nmod fixed_vec;\nmod par_collect_into;\nmod split_vec;\npub(crate) mod utils;\nmod vec;\n\npub use par_"
  },
  {
    "path": "src/collect_into/par_collect_into.rs",
    "chars": 2590,
    "preview": "use crate::Params;\nuse crate::generic_values::runner_results::{Fallibility, Infallible};\nuse crate::generic_values::{Tra"
  },
  {
    "path": "src/collect_into/split_vec.rs",
    "chars": 2530,
    "preview": "use super::collect::{map_collect_into, xap_collect_into, xap_try_collect_into};\nuse super::par_collect_into::ParCollectI"
  },
  {
    "path": "src/collect_into/utils.rs",
    "chars": 1131,
    "preview": "use alloc::vec::Vec;\nuse orx_pinned_vec::PinnedVec;\nuse orx_split_vec::{GrowthWithConstantTimeAccess, SplitVec};\n\npub fn"
  },
  {
    "path": "src/collect_into/vec.rs",
    "chars": 2859,
    "preview": "use super::par_collect_into::ParCollectIntoCore;\nuse crate::Params;\nuse crate::collect_into::collect::map_collect_into;\n"
  },
  {
    "path": "src/computational_variants/fallible_option.rs",
    "chars": 3653,
    "preview": "use crate::{\n    ChunkSize, IterationOrder, NumThreads, ParCollectInto, ParIterResult,\n    par_iter_option::{ParIterOpti"
  },
  {
    "path": "src/computational_variants/fallible_result/map_result.rs",
    "chars": 3483,
    "preview": "use crate::computational_variants::ParMap;\nuse crate::executor::parallel_compute as prc;\nuse crate::par_iter_result::{In"
  },
  {
    "path": "src/computational_variants/fallible_result/mod.rs",
    "chars": 148,
    "preview": "mod map_result;\nmod par_result;\nmod xap_result;\n\npub use map_result::ParMapResult;\npub use par_result::ParResult;\npub us"
  },
  {
    "path": "src/computational_variants/fallible_result/par_result.rs",
    "chars": 3293,
    "preview": "use crate::computational_variants::Par;\nuse crate::executor::parallel_compute as prc;\nuse crate::par_iter_result::{IntoR"
  },
  {
    "path": "src/computational_variants/fallible_result/xap_result.rs",
    "chars": 4074,
    "preview": "use crate::computational_variants::ParXap;\nuse crate::executor::parallel_compute as prc;\nuse crate::generic_values::Tran"
  },
  {
    "path": "src/computational_variants/map.rs",
    "chars": 6762,
    "preview": "use super::xap::ParXap;\nuse crate::computational_variants::fallible_result::ParMapResult;\nuse crate::executor::parallel_"
  },
  {
    "path": "src/computational_variants/mod.rs",
    "chars": 412,
    "preview": "#[cfg(test)]\nmod tests;\n\n/// A parallel iterator for which the computation either completely succeeds,\n/// or fails and "
  },
  {
    "path": "src/computational_variants/par.rs",
    "chars": 7127,
    "preview": "use super::{map::ParMap, xap::ParXap};\nuse crate::computational_variants::fallible_result::ParResult;\nuse crate::executo"
  },
  {
    "path": "src/computational_variants/tests/copied.rs",
    "chars": 3620,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::vec::Vec;\nuse test_case::test_matrix;\n\nfn input<O: FromIterator<usize>>(n: usi"
  },
  {
    "path": "src/computational_variants/tests/count.rs",
    "chars": 3065,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse test_c"
  },
  {
    "path": "src/computational_variants/tests/enumerate.rs",
    "chars": 1650,
    "preview": "use std::string::ToString;\n\nuse crate::{test_utils::*, *};\nuse alloc::vec::Vec;\nuse test_case::test_matrix;\n\n#[test_matr"
  },
  {
    "path": "src/computational_variants/tests/fallible_option.rs",
    "chars": 2434,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse test_c"
  },
  {
    "path": "src/computational_variants/tests/fallible_result.rs",
    "chars": 2777,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse test_c"
  },
  {
    "path": "src/computational_variants/tests/flatten.rs",
    "chars": 3199,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse alloc::{format, vec};\nuse"
  },
  {
    "path": "src/computational_variants/tests/for_each.rs",
    "chars": 3782,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse orx_co"
  },
  {
    "path": "src/computational_variants/tests/inspect.rs",
    "chars": 3897,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse orx_co"
  },
  {
    "path": "src/computational_variants/tests/iter_consuming.rs",
    "chars": 4309,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec;\nuse alloc::vec:"
  },
  {
    "path": "src/computational_variants/tests/iter_ref.rs",
    "chars": 4040,
    "preview": "use crate::{collect_into::ParCollectIntoCore, test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString"
  },
  {
    "path": "src/computational_variants/tests/map/collect.rs",
    "chars": 1459,
    "preview": "use crate::collect_into::collect::map_collect_into;\nuse crate::{IterationOrder, Params, runner::DefaultRunner};\nuse allo"
  },
  {
    "path": "src/computational_variants/tests/map/find.rs",
    "chars": 1333,
    "preview": "use crate::{Params, default_fns::map_self, executor::parallel_compute, runner::DefaultRunner};\nuse alloc::format;\nuse al"
  },
  {
    "path": "src/computational_variants/tests/map/mod.rs",
    "chars": 35,
    "preview": "mod collect;\nmod find;\nmod reduce;\n"
  },
  {
    "path": "src/computational_variants/tests/map/reduce.rs",
    "chars": 1595,
    "preview": "use crate::{Params, default_fns::map_self, executor::parallel_compute, runner::DefaultRunner};\nuse alloc::format;\nuse al"
  },
  {
    "path": "src/computational_variants/tests/min_max.rs",
    "chars": 7272,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse core::cmp::Ordering;\nuse "
  },
  {
    "path": "src/computational_variants/tests/mod.rs",
    "chars": 229,
    "preview": "mod copied;\nmod count;\nmod enumerate;\nmod fallible_option;\nmod fallible_result;\nmod flatten;\nmod for_each;\nmod inspect;\n"
  },
  {
    "path": "src/computational_variants/tests/range.rs",
    "chars": 3240,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::string::{String, ToString};\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse orx_fixed"
  },
  {
    "path": "src/computational_variants/tests/slice.rs",
    "chars": 3999,
    "preview": "use crate::{collect_into::ParCollectIntoCore, test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString"
  },
  {
    "path": "src/computational_variants/tests/sum.rs",
    "chars": 3193,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse test_case::test_matrix;\n\n"
  },
  {
    "path": "src/computational_variants/tests/vectors.rs",
    "chars": 4033,
    "preview": "use crate::{test_utils::*, *};\nuse alloc::format;\nuse alloc::string::{String, ToString};\nuse alloc::vec;\nuse alloc::vec:"
  },
  {
    "path": "src/computational_variants/tests/xap/collect.rs",
    "chars": 4070,
    "preview": "use crate::ParIter;\nuse crate::computational_variants::ParXap;\nuse crate::generic_values::Vector;\nuse crate::runner::Def"
  },
  {
    "path": "src/computational_variants/tests/xap/find.rs",
    "chars": 1644,
    "preview": "use crate::ParIter;\nuse crate::Params;\nuse crate::computational_variants::ParXap;\nuse crate::generic_values::Vector;\nuse"
  },
  {
    "path": "src/computational_variants/tests/xap/mod.rs",
    "chars": 35,
    "preview": "mod collect;\nmod find;\nmod reduce;\n"
  },
  {
    "path": "src/computational_variants/tests/xap/reduce.rs",
    "chars": 1878,
    "preview": "use crate::ParIter;\nuse crate::Params;\nuse crate::computational_variants::ParXap;\nuse crate::generic_values::Vector;\nuse"
  },
  {
    "path": "src/computational_variants/xap.rs",
    "chars": 7325,
    "preview": "use crate::computational_variants::fallible_result::ParXapResult;\nuse crate::executor::parallel_compute as prc;\nuse crat"
  },
  {
    "path": "src/default_fns.rs",
    "chars": 992,
    "preview": "use core::ops::Add;\n\n#[inline(always)]\npub fn map_self<T>(input: T) -> T {\n    input\n}\n\n#[inline(always)]\npub fn map_cou"
  },
  {
    "path": "src/enumerate/mod.rs",
    "chars": 802,
    "preview": "use crate::{ParIter, ParallelRunner};\n\n/// A parallel iterator with a known and fixed size,\n/// meaning all transformati"
  },
  {
    "path": "src/env.rs",
    "chars": 616,
    "preview": "use core::num::NonZeroUsize;\n\n#[cfg(feature = \"std\")]\nconst MAX_NUM_THREADS_ENV_VARIABLE: &str = \"ORX_PARALLEL_MAX_NUM_T"
  },
  {
    "path": "src/executor/computation_kind.rs",
    "chars": 353,
    "preview": "/// Computation kind.\n#[derive(Clone, Copy)]\npub enum ComputationKind {\n    /// Computation where outputs are collected "
  },
  {
    "path": "src/executor/executor_with_diagnostics/mod.rs",
    "chars": 123,
    "preview": "mod parallel_executor;\nmod shared_state;\nmod thread_executor;\n\npub use parallel_executor::ParallelExecutorWithDiagnostic"
  },
  {
    "path": "src/executor/executor_with_diagnostics/parallel_executor.rs",
    "chars": 3522,
    "preview": "use super::{\n    shared_state::SharedStateWithDiagnostics, thread_executor::ThreadExecutorWithDiagnostics,\n};\nuse crate:"
  },
  {
    "path": "src/executor/executor_with_diagnostics/shared_state.rs",
    "chars": 1541,
    "preview": "use alloc::vec::Vec;\nuse orx_concurrent_bag::ConcurrentBag;\nuse std::println;\n\npub struct SharedStateWithDiagnostics<S> "
  },
  {
    "path": "src/executor/executor_with_diagnostics/thread_executor.rs",
    "chars": 1556,
    "preview": "use super::shared_state::SharedStateWithDiagnostics;\nuse crate::{ParallelExecutor, ThreadExecutor};\nuse alloc::vec;\nuse "
  },
  {
    "path": "src/executor/fixed_chunk_executor/chunk_size.rs",
    "chars": 2930,
    "preview": "use crate::{parameters::ChunkSize, runner::ComputationKind};\nuse core::num::NonZeroUsize;\n\nconst MAX_CHUNK_SIZE: usize ="
  },
  {
    "path": "src/executor/fixed_chunk_executor/mod.rs",
    "chars": 106,
    "preview": "mod chunk_size;\nmod parallel_executor;\nmod thread_executor;\n\npub use parallel_executor::FixedChunkRunner;\n"
  },
  {
    "path": "src/executor/fixed_chunk_executor/parallel_executor.rs",
    "chars": 4293,
    "preview": "use super::{chunk_size::ResolvedChunkSize, thread_executor::FixedChunkThreadExecutor};\nuse crate::runner::ComputationKin"
  },
  {
    "path": "src/executor/fixed_chunk_executor/thread_executor.rs",
    "chars": 592,
    "preview": "use crate::executor::thread_executor::ThreadExecutor;\nuse orx_concurrent_iter::ConcurrentIter;\n\npub struct FixedChunkThr"
  },
  {
    "path": "src/executor/mod.rs",
    "chars": 456,
    "preview": "#[cfg(feature = \"std\")]\nmod executor_with_diagnostics;\nmod fixed_chunk_executor;\npub(crate) mod parallel_compute;\nmod pa"
  },
  {
    "path": "src/executor/parallel_compute/collect_arbitrary.rs",
    "chars": 2636,
    "preview": "use crate::Params;\nuse crate::executor::thread_compute as th;\nuse crate::generic_values::Values;\nuse crate::generic_valu"
  },
  {
    "path": "src/executor/parallel_compute/collect_ordered.rs",
    "chars": 2106,
    "preview": "use crate::Params;\nuse crate::executor::thread_compute as th;\nuse crate::generic_values::Values;\nuse crate::generic_valu"
  },
  {
    "path": "src/executor/parallel_compute/mod.rs",
    "chars": 135,
    "preview": "pub(crate) mod collect_arbitrary;\npub(crate) mod collect_ordered;\npub(crate) mod next;\npub(crate) mod next_any;\npub(crat"
  },
  {
    "path": "src/executor/parallel_compute/next.rs",
    "chars": 2147,
    "preview": "use crate::Params;\nuse crate::executor::thread_compute as th;\nuse crate::generic_values::Values;\nuse crate::generic_valu"
  },
  {
    "path": "src/executor/parallel_compute/next_any.rs",
    "chars": 1683,
    "preview": "use crate::Params;\nuse crate::executor::thread_compute as th;\nuse crate::generic_values::Values;\nuse crate::generic_valu"
  },
  {
    "path": "src/executor/parallel_compute/reduce.rs",
    "chars": 1911,
    "preview": "use crate::Params;\nuse crate::executor::thread_compute as th;\nuse crate::generic_values::Values;\nuse crate::generic_valu"
  },
  {
    "path": "src/executor/parallel_executor.rs",
    "chars": 1912,
    "preview": "use super::thread_executor::ThreadExecutor;\nuse crate::{\n    parameters::Params,\n    runner::{ComputationKind, NumSpawne"
  },
  {
    "path": "src/executor/thread_compute/collect_arbitrary.rs",
    "chars": 5065,
    "preview": "use crate::ThreadExecutor;\nuse crate::generic_values::Values;\nuse crate::generic_values::runner_results::{Stop, ThreadCo"
  },
  {
    "path": "src/executor/thread_compute/collect_ordered.rs",
    "chars": 5575,
    "preview": "use crate::ThreadExecutor;\nuse crate::generic_values::Values;\nuse crate::generic_values::runner_results::{StopWithIdx, T"
  },
  {
    "path": "src/executor/thread_compute/mod.rs",
    "chars": 135,
    "preview": "pub(super) mod collect_arbitrary;\npub(super) mod collect_ordered;\npub(super) mod next;\npub(super) mod next_any;\npub(supe"
  },
  {
    "path": "src/executor/thread_compute/next.rs",
    "chars": 6266,
    "preview": "use crate::{\n    ThreadExecutor,\n    generic_values::Values,\n    generic_values::runner_results::{Next, NextWithIdx},\n};"
  },
  {
    "path": "src/executor/thread_compute/next_any.rs",
    "chars": 6087,
    "preview": "use crate::{\n    ThreadExecutor,\n    generic_values::Values,\n    generic_values::runner_results::{Fallibility, Next},\n};"
  },
  {
    "path": "src/executor/thread_compute/reduce.rs",
    "chars": 5674,
    "preview": "use crate::{\n    ThreadExecutor,\n    generic_values::{\n        Values,\n        runner_results::{Reduce, StopReduce},\n   "
  },
  {
    "path": "src/executor/thread_executor.rs",
    "chars": 1252,
    "preview": "use orx_concurrent_iter::ConcurrentIter;\n\n/// Thread executor responsible for executing the tasks assigned to the thread"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/mod.rs",
    "chars": 202,
    "preview": "#[cfg(test)]\nmod tests;\n\n/// Sequential variant for merging two sorted slices into one sorted slice.\npub mod seq;\n\n/// P"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/par.rs",
    "chars": 6269,
    "preview": "use crate::experiment::algorithms::merge_sorted_slices::seq::{\n    ParamsSeqMergeSortedSlices, bin_search_idx, seq_merge"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/seq.rs",
    "chars": 11578,
    "preview": "use crate::experiment::data_structures::{slice_dst::SliceDst, slice_src::SliceSrc};\nuse core::cmp::Ordering;\n\npub(super)"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/tests/inputs.rs",
    "chars": 1087,
    "preview": "use alloc::string::{String, ToString};\nuse alloc::vec::Vec;\nuse rand::prelude::*;\nuse rand_chacha::ChaCha8Rng;\n\n#[derive"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/tests/mod.rs",
    "chars": 30,
    "preview": "mod inputs;\nmod par;\nmod seq;\n"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/tests/par.rs",
    "chars": 3859,
    "preview": "use super::inputs::{SortKind, sorted_slices};\nuse crate::experiment::algorithms::merge_sorted_slices::par::{\n    ParamsP"
  },
  {
    "path": "src/experiment/algorithms/merge_sorted_slices/tests/seq.rs",
    "chars": 2056,
    "preview": "use super::inputs::{SortKind, sorted_slices};\nuse crate::experiment::algorithms::merge_sorted_slices::seq::{\n    ParamsS"
  },
  {
    "path": "src/experiment/algorithms/mod.rs",
    "chars": 80,
    "preview": "/// Merge two sorted slices into one sorted slice.\npub mod merge_sorted_slices;\n"
  },
  {
    "path": "src/experiment/data_structures/mod.rs",
    "chars": 607,
    "preview": "#[cfg(test)]\nmod tests;\n\n/// A raw slice of contiguous data.\npub mod slice;\n/// A raw slice of contiguous data with un-i"
  },
  {
    "path": "src/experiment/data_structures/slice.rs",
    "chars": 4047,
    "preview": "use core::{marker::PhantomData, ptr::slice_from_raw_parts};\n\n/// A raw slice of contiguous data.\npub struct Slice<'a, T:"
  },
  {
    "path": "src/experiment/data_structures/slice_dst.rs",
    "chars": 3040,
    "preview": "use crate::experiment::data_structures::slice::{Slice, SliceSafe};\nuse crate::experiment::data_structures::slice_iter_pt"
  },
  {
    "path": "src/experiment/data_structures/slice_iter_ptr.rs",
    "chars": 4191,
    "preview": "use core::marker::PhantomData;\n\n/// Core structure for iterators over contiguous slices of data.\npub struct SliceIterPtr"
  },
  {
    "path": "src/experiment/data_structures/slice_iter_ptr_dst.rs",
    "chars": 3825,
    "preview": "use crate::experiment::data_structures::slice_iter_ptr_src::SliceIterPtrSrc;\nuse crate::experiment::data_structures::{sl"
  },
  {
    "path": "src/experiment/data_structures/slice_iter_ptr_src.rs",
    "chars": 3539,
    "preview": "use crate::experiment::data_structures::{slice_iter_ptr::SliceIterPtr, slice_src::SliceSrc};\nuse core::slice::from_raw_p"
  },
  {
    "path": "src/experiment/data_structures/slice_src.rs",
    "chars": 3085,
    "preview": "use crate::experiment::data_structures::{\n    slice::{Slice, SliceSafe},\n    slice_iter_ptr_src::SliceIterPtrSrc,\n};\n\n//"
  },
  {
    "path": "src/experiment/data_structures/tests/mod.rs",
    "chars": 11,
    "preview": "mod slice;\n"
  },
  {
    "path": "src/experiment/data_structures/tests/slice.rs",
    "chars": 1824,
    "preview": "use crate::experiment::data_structures::slice::{Slice, SliceSafe};\nuse alloc::vec::Vec;\nuse std::string::ToString;\nuse t"
  },
  {
    "path": "src/experiment/mod.rs",
    "chars": 112,
    "preview": "/// Data structures used for internal algorithms.\npub mod data_structures;\n\n/// Algorithms.\npub mod algorithms;\n"
  },
  {
    "path": "src/generic_iterator/collect.rs",
    "chars": 684,
    "preview": "use super::iter::GenericIterator;\nuse crate::ParIter;\nuse alloc::vec::Vec;\n\nimpl<T, S, R, O> GenericIterator<T, S, R, O>"
  },
  {
    "path": "src/generic_iterator/early_exit.rs",
    "chars": 1324,
    "preview": "use super::iter::GenericIterator;\nuse crate::{IterationOrder, ParIter};\n\nimpl<T, S, R, O> GenericIterator<T, S, R, O>\nwh"
  },
  {
    "path": "src/generic_iterator/iter.rs",
    "chars": 1493,
    "preview": "use crate::ParIter;\n\n/// An iterator that generalizes over:\n///\n/// * sequential iterators,\n/// * rayon's parallel itera"
  },
  {
    "path": "src/generic_iterator/mod.rs",
    "chars": 104,
    "preview": "mod collect;\nmod early_exit;\nmod iter;\nmod reduce;\nmod transformations;\n\npub use iter::GenericIterator;\n"
  },
  {
    "path": "src/generic_iterator/reduce.rs",
    "chars": 4905,
    "preview": "use super::iter::GenericIterator;\nuse crate::ParIter;\nuse core::cmp::Ordering;\n\nimpl<T, S, R, O> GenericIterator<T, S, R"
  },
  {
    "path": "src/generic_iterator/transformations.rs",
    "chars": 7219,
    "preview": "use super::iter::GenericIterator;\nuse crate::ParIter;\n\nimpl<T, S, R, O> GenericIterator<T, S, R, O>\nwhere\n    T: Send + "
  },
  {
    "path": "src/generic_values/fallible_iterators/mod.rs",
    "chars": 59,
    "preview": "mod result_of_iter;\n\npub use result_of_iter::ResultOfIter;\n"
  },
  {
    "path": "src/generic_values/fallible_iterators/result_of_iter.rs",
    "chars": 729,
    "preview": "pub struct ResultOfIter<I, E>\nwhere\n    I: Iterator,\n{\n    iter: Option<I>,\n    error: Option<E>,\n}\n\nimpl<I, E> ResultOf"
  },
  {
    "path": "src/generic_values/mod.rs",
    "chars": 568,
    "preview": "pub mod fallible_iterators;\nmod option;\nmod option_result;\nmod result;\npub(crate) mod runner_results;\nmod transformable_"
  },
  {
    "path": "src/generic_values/option.rs",
    "chars": 5395,
    "preview": "use super::{TransformableValues, Vector};\nuse crate::generic_values::Values;\nuse crate::generic_values::{\n    option_res"
  },
  {
    "path": "src/generic_values/option_result.rs",
    "chars": 3009,
    "preview": "use crate::generic_values::Values;\nuse crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Next, Order"
  },
  {
    "path": "src/generic_values/result.rs",
    "chars": 2952,
    "preview": "use crate::generic_values::Values;\nuse crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Next, Order"
  },
  {
    "path": "src/generic_values/runner_results/collect_arbitrary.rs",
    "chars": 2183,
    "preview": "use crate::generic_values::{Values, runner_results::Fallibility};\nuse orx_fixed_vec::IntoConcurrentPinnedVec;\n\npub enum "
  },
  {
    "path": "src/generic_values/runner_results/collect_ordered.rs",
    "chars": 4260,
    "preview": "use crate::{\n    generic_values::{Values, runner_results::Fallibility},\n    heap_sort::heap_sort_into,\n};\nuse alloc::vec"
  },
  {
    "path": "src/generic_values/runner_results/collect_sequential.rs",
    "chars": 836,
    "preview": "use crate::generic_values::runner_results::{\n    Fallibility, Fallible, Infallible, Stop, fallibility::Never,\n};\n\npub en"
  },
  {
    "path": "src/generic_values/runner_results/fallibility.rs",
    "chars": 4456,
    "preview": "use crate::generic_values::{\n    Values,\n    runner_results::{\n        ArbitraryPush, OrderedPush, Reduce, SequentialPus"
  },
  {
    "path": "src/generic_values/runner_results/mod.rs",
    "chars": 512,
    "preview": "mod collect_arbitrary;\nmod collect_ordered;\nmod collect_sequential;\nmod fallibility;\nmod next;\nmod reduce;\nmod stop;\n\npu"
  },
  {
    "path": "src/generic_values/runner_results/next.rs",
    "chars": 1406,
    "preview": "use crate::generic_values::{Values, runner_results::Fallibility};\n\npub enum Next<V: Values> {\n    Done {\n        value: "
  },
  {
    "path": "src/generic_values/runner_results/reduce.rs",
    "chars": 1096,
    "preview": "use crate::generic_values::{Values, runner_results::Fallibility};\n\npub enum Reduce<V: Values> {\n    Done {\n        acc: "
  },
  {
    "path": "src/generic_values/runner_results/stop.rs",
    "chars": 403,
    "preview": "use crate::generic_values::{Values, runner_results::Fallibility};\n\npub enum Stop<E> {\n    DueToWhile,\n    DueToError { e"
  },
  {
    "path": "src/generic_values/transformable_values.rs",
    "chars": 2138,
    "preview": "use crate::generic_values::{Values, runner_results::Fallible};\n\npub trait TransformableValues: Values {\n    fn map<M, O>"
  },
  {
    "path": "src/generic_values/values.rs",
    "chars": 2197,
    "preview": "use crate::generic_values::runner_results::{\n    ArbitraryPush, Fallibility, Next, OrderedPush, Reduce, SequentialPush, "
  },
  {
    "path": "src/generic_values/vector.rs",
    "chars": 5611,
    "preview": "use super::transformable_values::TransformableValues;\nuse crate::generic_values::{\n    Values, VectorResult, WhilstAtom,"
  },
  {
    "path": "src/generic_values/vector_result.rs",
    "chars": 3969,
    "preview": "use crate::generic_values::Values;\nuse crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Next, Order"
  },
  {
    "path": "src/generic_values/whilst_atom.rs",
    "chars": 7323,
    "preview": "use crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Infallible, Next, OrderedPush, Reduce, Sequent"
  },
  {
    "path": "src/generic_values/whilst_atom_result.rs",
    "chars": 3264,
    "preview": "use crate::generic_values::Values;\nuse crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Next, Order"
  },
  {
    "path": "src/generic_values/whilst_iterators/mod.rs",
    "chars": 165,
    "preview": "mod whilst_atom_flat_map;\nmod whilst_option_flat_map;\n\npub use whilst_atom_flat_map::WhilstAtomFlatMapIter;\npub use whil"
  },
  {
    "path": "src/generic_values/whilst_iterators/whilst_atom_flat_map.rs",
    "chars": 1362,
    "preview": "use crate::generic_values::whilst_atom::WhilstAtom;\n\npub struct WhilstAtomFlatMapIter<Vo>\nwhere\n    Vo: IntoIterator,\n{\n"
  },
  {
    "path": "src/generic_values/whilst_iterators/whilst_option_flat_map.rs",
    "chars": 1639,
    "preview": "use crate::generic_values::{WhilstAtom, WhilstOption};\n\npub struct WhilstOptionFlatMapIter<Vo>\nwhere\n    Vo: IntoIterato"
  },
  {
    "path": "src/generic_values/whilst_option.rs",
    "chars": 7969,
    "preview": "use crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Infallible, Next, OrderedPush, Reduce, Sequent"
  },
  {
    "path": "src/generic_values/whilst_option_result.rs",
    "chars": 3652,
    "preview": "use crate::generic_values::Values;\nuse crate::generic_values::runner_results::{\n    ArbitraryPush, Fallible, Next, Order"
  },
  {
    "path": "src/generic_values/whilst_vector.rs",
    "chars": 9082,
    "preview": "use super::transformable_values::TransformableValues;\nuse crate::generic_values::{\n    Values, WhilstAtom,\n    runner_re"
  },
  {
    "path": "src/generic_values/whilst_vector_result.rs",
    "chars": 5265,
    "preview": "use crate::generic_values::{\n    Values, WhilstAtom,\n    runner_results::{ArbitraryPush, Fallible, Next, OrderedPush, Re"
  },
  {
    "path": "src/heap_sort.rs",
    "chars": 1917,
    "preview": "use alloc::vec;\nuse alloc::vec::Vec;\nuse orx_pinned_vec::PinnedVec;\nuse orx_priority_queue::{BinaryHeap, PriorityQueue};"
  },
  {
    "path": "src/into_par_iter.rs",
    "chars": 2152,
    "preview": "use crate::{Params, computational_variants::Par, runner::DefaultRunner};\nuse orx_concurrent_iter::{ConcurrentIter, IntoC"
  },
  {
    "path": "src/iter/mod.rs",
    "chars": 120,
    "preview": "mod recursive;\nmod special_iterators;\n\npub use recursive::IntoParIterRec;\npub use special_iterators::{ParEmpty, empty};\n"
  },
  {
    "path": "src/iter/recursive/into_par_rec_iter.rs",
    "chars": 20842,
    "preview": "use crate::{DefaultRunner, Params, computational_variants::Par};\nuse orx_concurrent_recursive_iter::{ConcurrentRecursive"
  },
  {
    "path": "src/iter/recursive/mod.rs",
    "chars": 85,
    "preview": "mod into_par_rec_iter;\nmod rec_par_iter;\n\npub use into_par_rec_iter::IntoParIterRec;\n"
  },
  {
    "path": "src/iter/recursive/rec_par_iter.rs",
    "chars": 4412,
    "preview": "use crate::{\n    ParIter, ParallelRunner,\n    computational_variants::{Par, ParMap, ParXap},\n    generic_values::{Transf"
  },
  {
    "path": "src/iter/special_iterators.rs",
    "chars": 458,
    "preview": "use crate::{computational_variants::Par, runner::DefaultRunner};\nuse orx_concurrent_iter::implementations::ConIterEmpty;"
  }
]

// ... and 141 more files (download for full content)

About this extraction

This page contains the full source code of the orxfun/orx-parallel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 341 files (1.1 MB), approximately 320.1k tokens, and a symbol index with 2306 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!