mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge branch 'development' into feature/add-time-date-classes
# Conflicts: # .gitignore # include/etl/platform.h # include/etl/ratio.h # test/CMakeLists.txt # test/test_ratio.cpp # test/vs2022/etl.vcxproj # test/vs2022/etl.vcxproj.filters
This commit is contained in:
commit
fedf429d02
4
.github/workflows/clang-c++11.yml
vendored
4
.github/workflows/clang-c++11.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
4
.github/workflows/clang-c++14.yml
vendored
4
.github/workflows/clang-c++14.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
4
.github/workflows/clang-c++17.yml
vendored
4
.github/workflows/clang-c++17.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
22
.github/workflows/clang-c++20.yml
vendored
22
.github/workflows/clang-c++20.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
|
||||
- name: Install newer Clang
|
||||
@ -44,7 +44,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
|
||||
- name: Install newer Clang
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Temporary fix. See https://github.com/actions/runner-images/issues/8659
|
||||
- name: Install newer Clang
|
||||
@ -99,10 +99,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-12]
|
||||
os: [macos-13]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -121,10 +121,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-12]
|
||||
os: [macos-13]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -143,10 +143,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-12]
|
||||
os: [macos-13]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -165,10 +165,10 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-12]
|
||||
os: [macos-13]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
72
.github/workflows/clang-syntax-checks.yml
vendored
72
.github/workflows/clang-syntax-checks.yml
vendored
@ -14,13 +14,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++03
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -32,13 +32,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++03
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -50,13 +50,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -68,13 +68,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -86,13 +86,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -104,13 +104,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -122,13 +122,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -140,13 +140,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -158,13 +158,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -176,13 +176,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -194,13 +194,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -212,13 +212,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -230,13 +230,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -248,13 +248,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -266,13 +266,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -284,13 +284,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -302,13 +302,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -320,12 +320,12 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
clang --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
4
.github/workflows/gcc-c++11.yml
vendored
4
.github/workflows/gcc-c++11.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
4
.github/workflows/gcc-c++14.yml
vendored
4
.github/workflows/gcc-c++14.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
4
.github/workflows/gcc-c++17.yml
vendored
4
.github/workflows/gcc-c++17.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
8
.github/workflows/gcc-c++20.yml
vendored
8
.github/workflows/gcc-c++20.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
@ -81,7 +81,7 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
||||
72
.github/workflows/gcc-syntax-checks.yml
vendored
72
.github/workflows/gcc-syntax-checks.yml
vendored
@ -14,13 +14,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++03
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -32,13 +32,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++03
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -50,13 +50,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -68,13 +68,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -86,13 +86,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -104,13 +104,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++11
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -122,13 +122,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -140,13 +140,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -158,13 +158,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -176,13 +176,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++14
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -194,13 +194,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -212,13 +212,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -230,13 +230,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -248,13 +248,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++17
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -266,13 +266,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -284,13 +284,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -302,13 +302,13 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
|
||||
@ -320,12 +320,12 @@ jobs:
|
||||
os: [ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check/c++20
|
||||
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/syntax_check
|
||||
gcc --version
|
||||
make -j $(getconf _NPROCESSORS_ONLN)
|
||||
8
.github/workflows/msvc.yml
vendored
8
.github/workflows/msvc.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@ -33,7 +33,7 @@ jobs:
|
||||
runs-on: [windows-2022]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@ -55,7 +55,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@ -77,7 +77,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -388,6 +388,15 @@ support/time remaining test.xlsx
|
||||
test/vs2022/Debug MSVC C++20 - Force C++03
|
||||
test/vs2022/Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser
|
||||
test/test_file_list.txt
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/CopilotIndices
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/FileContentIndex
|
||||
examples/QueuedMessageRouter/vs2022/.vs/QueuedMessageRouter/v17
|
||||
test/etl_error_handler/assert_errors/build-make
|
||||
test/etl_error_handler/assert_function/build-make
|
||||
test/syntax_check/bgcc
|
||||
test/syntax_check/bclang
|
||||
test/vs2022/Debug Clang C++20
|
||||
test/vs2022/Debug MSVC C++20 - Forve C++03 - No virtual messages
|
||||
test/reflog.txt
|
||||
test/etl_error_handler/assert_function/build-make
|
||||
test/syntax_check/bgcc
|
||||
|
||||
13
CONTRIBUTING.md
Normal file
13
CONTRIBUTING.md
Normal file
@ -0,0 +1,13 @@
|
||||
# How to contribute
|
||||
|
||||
If your are considering creating a pull request, please observe the following:
|
||||
|
||||
- If you are adding or modifying a feature, add *new* unit tests that test that feature.
|
||||
- If you are fixing a bug, add a unit test that *fails* before the bug fix is implemented.
|
||||
- Do not initiate a pull request until all of the units tests pass.
|
||||
- Branches should be based on the branch `master`.
|
||||
|
||||
There is a project file for VS2022 for C++14, 17, 20, and bash scripts that run the tests for C++11, 14, 17, 20 under Linux with GCC and Clang.
|
||||
|
||||
If you are thinking of adding a new feature then raise this on the GitHub Issues page for disccussion as the maintainers and user of the ETL may have questions or suggestions.
|
||||
It is possible that the maintainer of the ETL or another contributor is already working on the same or related feature.
|
||||
@ -69,7 +69,7 @@ The library is intended for any compiler that supports C++98/03/11/14/17/20.
|
||||
- Checksums & hash functions
|
||||
- Variants (a type that can store many types in a type-safe interface)
|
||||
- Choice of asserts, exceptions, error handler or no checks on errors
|
||||
- Unit tested (currently over 6480 tests), using VS2019, GCC 8.1.0, , GCC 9.3.0, Clang 9.0.0 & 10.0.0
|
||||
- Unit tested (currently over 9400 tests), using VS2022, GCC 12, Clang 14.
|
||||
- Many utilities for template support.
|
||||
- Easy to read and documented source.
|
||||
- Free support via email, GitHub and Slack
|
||||
|
||||
@ -16,11 +16,5 @@ install:
|
||||
build:
|
||||
project: test/vs2022/etl.vcxproj
|
||||
verbosity: minimal
|
||||
notifications:
|
||||
- provider: Webhook
|
||||
url: https://hooks.slack.com/services/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
|
||||
method: POST
|
||||
on_build_success: true
|
||||
on_build_failure: true
|
||||
on_build_status_changed: true
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Embedded Template Library ETL",
|
||||
"version": "20.39.0",
|
||||
"version": "20.40.0",
|
||||
"authors": {
|
||||
"name": "John Wellbelove",
|
||||
"email": "john.wellbelove@etlcpp.com"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
name=Embedded Template Library ETL
|
||||
version=20.39.0
|
||||
version=20.40.0
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
license=MIT
|
||||
|
||||
@ -13,7 +13,7 @@ function(determine_version_with_git)
|
||||
git_describe(VERSION ${ARGN})
|
||||
string(FIND ${VERSION} "." VALID_VERSION)
|
||||
if(VALID_VERSION EQUAL -1)
|
||||
if(PROJECT_IS_TOP_LEVEL)
|
||||
if(CMAKE_CURRENT_LIST_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
# only warn if this is the top-level project, since we may be
|
||||
# building from a tarball as a subproject
|
||||
message(WARNING "Version string ${VERSION} retrieved with git describe is invalid")
|
||||
|
||||
@ -52,8 +52,6 @@ public:
|
||||
|
||||
typedef etl::message_router<Router, Message1, Message2, Message3> Base_t;
|
||||
|
||||
using Base_t::receive;
|
||||
|
||||
//***************************************************************************
|
||||
Router()
|
||||
: message_router(1)
|
||||
|
||||
@ -29,26 +29,26 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -1449,16 +1449,20 @@ namespace etl
|
||||
TCompare compare)
|
||||
{
|
||||
TIterator minimum = begin;
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
if (begin != end)
|
||||
{
|
||||
if (compare(*begin, *minimum))
|
||||
{
|
||||
minimum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
{
|
||||
if (compare(*begin, *minimum))
|
||||
{
|
||||
minimum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
return minimum;
|
||||
@ -1493,16 +1497,20 @@ namespace etl
|
||||
TCompare compare)
|
||||
{
|
||||
TIterator maximum = begin;
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
if (begin != end)
|
||||
{
|
||||
if (!compare(*begin, *maximum))
|
||||
{
|
||||
maximum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
{
|
||||
if (!compare(*begin, *maximum))
|
||||
{
|
||||
maximum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
return maximum;
|
||||
@ -1538,21 +1546,25 @@ namespace etl
|
||||
{
|
||||
TIterator minimum = begin;
|
||||
TIterator maximum = begin;
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
if (begin != end)
|
||||
{
|
||||
if (compare(*begin, *minimum))
|
||||
{
|
||||
minimum = begin;
|
||||
}
|
||||
|
||||
if (compare(*maximum, *begin))
|
||||
{
|
||||
maximum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
|
||||
while (begin != end)
|
||||
{
|
||||
if (compare(*begin, *minimum))
|
||||
{
|
||||
minimum = begin;
|
||||
}
|
||||
|
||||
if (compare(*maximum, *begin))
|
||||
{
|
||||
maximum = begin;
|
||||
}
|
||||
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<TIterator, TIterator>(minimum, maximum);
|
||||
|
||||
@ -36,6 +36,7 @@ SOFTWARE.
|
||||
#include "static_assert.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -71,6 +72,19 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Typed storage exception.
|
||||
//***************************************************************************
|
||||
class typed_storage_error : public alignment_exception
|
||||
{
|
||||
public:
|
||||
|
||||
typed_storage_error(string_type file_name_, numeric_type line_number_)
|
||||
: alignment_exception(ETL_ERROR_TEXT("typed_storage:error", ETL_ALIGNMENT_FILE_ID"B"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
/// Check that 'p' has 'required_alignment'.
|
||||
//*****************************************************************************
|
||||
@ -334,6 +348,167 @@ namespace etl
|
||||
template <size_t Length, typename T>
|
||||
using aligned_storage_as_t = typename aligned_storage_as<Length, T>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Wrapper class that provides a memory area and lets the user create an
|
||||
/// instance of T in this memory at runtime. This class also erases the
|
||||
/// destructor call of T, i.e. if typed_storage goes out of scope, the
|
||||
/// destructor if the wrapped type will not be called. This can be done
|
||||
/// explicitly by calling destroy().
|
||||
/// \tparam T Type of element stored in this instance of typed_storage.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class typed_storage
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
// Constructor
|
||||
typed_storage()
|
||||
: valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Default destructor which will NOT call the destructor of the object which
|
||||
/// was created by calling create().
|
||||
//***************************************************************************
|
||||
~typed_storage() = default;
|
||||
|
||||
//***************************************************************************
|
||||
/// Calls the destructor of the wrapped object and asserts if has_value() is false.
|
||||
//***************************************************************************
|
||||
void destroy()
|
||||
{
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
data.template get_reference<T>().~T();
|
||||
valid = false;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// \returns <b>true</b> if object has been constructed using create().
|
||||
/// \returns <b>false</b> otherwise.
|
||||
//***************************************************************************
|
||||
bool has_value() const
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Constructs the instance of T forwarding the given \p args to its constructor and
|
||||
/// asserts if has_value() is false.
|
||||
///
|
||||
/// \returns the instance of T which has been constructed in the internal byte array.
|
||||
//***************************************************************************
|
||||
template<typename... Args>
|
||||
reference create(Args&&... args)
|
||||
{
|
||||
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
valid = true;
|
||||
return *::new (data.template get_address<char>()) value_type(etl::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
//***************************************************************************
|
||||
/// Constructs the instance of T with type T1
|
||||
/// asserts if has_value() is false.
|
||||
///
|
||||
/// \returns the instance of T which has been constructed in the internal byte array.
|
||||
//***************************************************************************
|
||||
template<typename T1>
|
||||
reference create(const T1& t1)
|
||||
{
|
||||
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
valid = true;
|
||||
return *::new (data.template get_address<char>()) value_type(t1);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructs the instance of T with types T1, T2
|
||||
/// asserts if has_value() is false.
|
||||
///
|
||||
/// \returns the instance of T which has been constructed in the internal byte array.
|
||||
//***************************************************************************
|
||||
template<typename T1, typename T2>
|
||||
reference create(const T1& t1, const T2& t2)
|
||||
{
|
||||
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
valid = true;
|
||||
return *::new (data.template get_address<char>()) value_type(t1, t2);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructs the instance of T with types T1, T2, T3
|
||||
/// asserts if has_value() is false.
|
||||
///
|
||||
/// \returns the instance of T which has been constructed in the internal byte array.
|
||||
//***************************************************************************
|
||||
template<typename T1, typename T2, typename T3>
|
||||
reference create(const T1& t1, const T2& t2, const T3& t3)
|
||||
{
|
||||
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
valid = true;
|
||||
return *::new (data.template get_address<char>()) value_type(t1, t2, t3);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructs the instance of T with types T1, T2, T3, T4
|
||||
/// asserts if has_value() is false.
|
||||
///
|
||||
/// \returns the instance of T which has been constructed in the internal byte array.
|
||||
//***************************************************************************
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
|
||||
{
|
||||
ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
valid = true;
|
||||
return *::new (data.template get_address<char>()) value_type(t1, t2, t3, t4);
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// \returns a pointer of type T and asserts if has_value() is false.
|
||||
//***************************************************************************
|
||||
pointer operator->()
|
||||
{
|
||||
ETL_ASSERT(has_value(), ETL_ERROR(etl::typed_storage_error));
|
||||
return data.template get_address<value_type>();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// \returns a const pointer of type T and asserts if has_value() is false.
|
||||
//***************************************************************************
|
||||
const_pointer operator->() const
|
||||
{
|
||||
return operator->();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// \returns reference of type T and asserts if has_value() is false.
|
||||
//***************************************************************************
|
||||
reference operator*()
|
||||
{
|
||||
return *operator->();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// \returns const reference of type T and asserts if has_value() is false.
|
||||
//***************************************************************************
|
||||
const_reference operator*() const
|
||||
{
|
||||
return *operator->();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typename aligned_storage_as<sizeof(value_type), value_type>::type data;
|
||||
bool valid;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -239,19 +239,19 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR array_view(const TIterator begin_, const TIterator end_)
|
||||
: mbegin(etl::addressof(*begin_)),
|
||||
mend(etl::addressof(*begin_) + etl::distance(begin_, end_))
|
||||
: mbegin(etl::to_address(begin_)),
|
||||
mend(etl::to_address(begin_) + etl::distance(begin_, end_))
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Construct from C array
|
||||
/// Construct from iterator and size
|
||||
//*************************************************************************
|
||||
template <typename TIterator,
|
||||
typename TSize>
|
||||
ETL_CONSTEXPR array_view(const TIterator begin_, const TSize size_)
|
||||
: mbegin(etl::addressof(*begin_)),
|
||||
mend(etl::addressof(*begin_) + size_)
|
||||
: mbegin(etl::to_address(begin_)),
|
||||
mend(etl::to_address(begin_) + size_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -458,8 +458,8 @@ namespace etl
|
||||
template <typename TIterator>
|
||||
void assign(const TIterator begin_, const TIterator end_)
|
||||
{
|
||||
mbegin = etl::addressof(*begin_);
|
||||
mend = etl::addressof(*begin_) + etl::distance(begin_, end_);
|
||||
mbegin = etl::to_address(begin_);
|
||||
mend = etl::to_address(begin_) + etl::distance(begin_, end_);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -469,8 +469,8 @@ namespace etl
|
||||
typename TSize>
|
||||
void assign(const TIterator begin_, const TSize size_)
|
||||
{
|
||||
mbegin = etl::addressof(*begin_);
|
||||
mend = etl::addressof(*begin_) + size_;
|
||||
mbegin = etl::to_address(begin_);
|
||||
mend = etl::to_address(begin_) + size_;
|
||||
}
|
||||
|
||||
#if defined(ETL_ARRAY_VIEW_IS_MUTABLE)
|
||||
|
||||
@ -83,7 +83,7 @@ namespace etl
|
||||
// Only integral and pointer types are supported.
|
||||
//***************************************************************************
|
||||
|
||||
enum memory_order
|
||||
typedef enum memory_order
|
||||
{
|
||||
memory_order_relaxed = __ATOMIC_RELAXED,
|
||||
memory_order_consume = __ATOMIC_CONSUME,
|
||||
@ -91,13 +91,22 @@ namespace etl
|
||||
memory_order_release = __ATOMIC_RELEASE,
|
||||
memory_order_acq_rel = __ATOMIC_ACQ_REL,
|
||||
memory_order_seq_cst = __ATOMIC_SEQ_CST
|
||||
} memory_order;
|
||||
|
||||
template <bool Is_Always_Lock_Free>
|
||||
struct atomic_traits
|
||||
{
|
||||
static ETL_CONSTANT bool is_always_lock_free = Is_Always_Lock_Free;
|
||||
};
|
||||
|
||||
template <bool Is_Always_Lock_Free>
|
||||
ETL_CONSTANT bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
|
||||
|
||||
//***************************************************************************
|
||||
/// For all types except bool, pointers and types that are always lock free.
|
||||
//***************************************************************************
|
||||
template <typename T, bool integral_type = etl::is_integral<T>::value>
|
||||
class atomic
|
||||
class atomic : public atomic_traits<integral_type>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -389,7 +398,7 @@ namespace etl
|
||||
/// Specialisation for pointers
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class atomic<T*, false>
|
||||
class atomic<T*, false> : public atomic_traits<true>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -631,7 +640,7 @@ namespace etl
|
||||
/// Specialisation for bool
|
||||
//***************************************************************************
|
||||
template <>
|
||||
class atomic<bool, true>
|
||||
class atomic<bool, true> : public atomic_traits<true>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -794,7 +803,7 @@ namespace etl
|
||||
/// Uses a mutex to control access.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class atomic<T, false>
|
||||
class atomic<T, false> : public atomic_traits<false>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -1030,11 +1039,20 @@ namespace etl
|
||||
memory_order_seq_cst
|
||||
} memory_order;
|
||||
|
||||
template <bool Is_Always_Lock_Free>
|
||||
struct atomic_traits
|
||||
{
|
||||
static ETL_CONSTANT bool is_always_lock_free = Is_Always_Lock_Free;
|
||||
};
|
||||
|
||||
template <bool Is_Always_Lock_Free>
|
||||
ETL_CONSTANT bool atomic_traits<Is_Always_Lock_Free>::is_always_lock_free;
|
||||
|
||||
//***************************************************************************
|
||||
/// For all types except bool and pointers
|
||||
//***************************************************************************
|
||||
template <typename T, bool integral_type = etl::is_integral<T>::value>
|
||||
class atomic
|
||||
class atomic : public atomic_traits<integral_type>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -1440,7 +1458,7 @@ namespace etl
|
||||
/// Specialisation for pointers
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class atomic<T*, false>
|
||||
class atomic<T*, false> : public atomic_traits<true>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -1750,7 +1768,7 @@ namespace etl
|
||||
/// Specialisation for bool
|
||||
//***************************************************************************
|
||||
template <>
|
||||
class atomic<bool, true>
|
||||
class atomic<bool, true> : public atomic_traits<true>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -1973,7 +1991,7 @@ namespace etl
|
||||
/// Uses a mutex to control access.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class atomic<T, false>
|
||||
class atomic<T, false> : public atomic_traits<false>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -2234,3 +2252,4 @@ namespace etl
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -86,13 +86,13 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// The common base for a bip_buffer_spsc_atomic_base.
|
||||
//***************************************************************************
|
||||
template <size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
template <size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class bip_buffer_spsc_atomic_base
|
||||
{
|
||||
public:
|
||||
|
||||
/// The type used for determining the size of buffer.
|
||||
typedef typename etl::size_type_lookup<MEMORY_MODEL>::type size_type;
|
||||
typedef typename etl::size_type_lookup<Memory_Model>::type size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns true if the buffer is empty.
|
||||
@ -168,7 +168,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return RESERVED;
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -176,7 +176,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return RESERVED;
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -188,7 +188,7 @@ namespace etl
|
||||
: read(0)
|
||||
, write(0)
|
||||
, last(0)
|
||||
, RESERVED(reserved_)
|
||||
, Reserved(reserved_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ namespace etl
|
||||
etl::atomic<size_type> read;
|
||||
etl::atomic<size_type> write;
|
||||
etl::atomic<size_type> last;
|
||||
const size_type RESERVED;
|
||||
const size_type Reserved;
|
||||
|
||||
#if defined(ETL_POLYMORPHIC_SPSC_BIP_BUFFER_ATOMIC) || defined(ETL_POLYMORPHIC_CONTAINERS)
|
||||
public:
|
||||
@ -361,12 +361,12 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// A fixed capacity bipartite buffer.
|
||||
//***************************************************************************
|
||||
template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class ibip_buffer_spsc_atomic : public bip_buffer_spsc_atomic_base<MEMORY_MODEL>
|
||||
template <typename T, const size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class ibip_buffer_spsc_atomic : public bip_buffer_spsc_atomic_base<Memory_Model>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename etl::bip_buffer_spsc_atomic_base<MEMORY_MODEL> base_t;
|
||||
typedef typename etl::bip_buffer_spsc_atomic_base<Memory_Model> base_t;
|
||||
using base_t::reset;
|
||||
using base_t::get_read_reserve;
|
||||
using base_t::apply_read_reserve;
|
||||
@ -486,15 +486,15 @@ namespace etl
|
||||
/// A fixed capacity bipartite buffer.
|
||||
/// This buffer supports concurrent access by one producer and one consumer.
|
||||
/// \tparam T The type this buffer should support.
|
||||
/// \tparam SIZE The maximum capacity of the buffer.
|
||||
/// \tparam MEMORY_MODEL The memory model for the buffer. Determines the type of the internal counter variables.
|
||||
/// \tparam Size The maximum capacity of the buffer.
|
||||
/// \tparam Memory_Model The memory model for the buffer. Determines the type of the internal counter variables.
|
||||
//***************************************************************************
|
||||
template <typename T, const size_t SIZE, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class bip_buffer_spsc_atomic : public ibip_buffer_spsc_atomic<T, MEMORY_MODEL>
|
||||
template <typename T, const size_t Size, const size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class bip_buffer_spsc_atomic : public ibip_buffer_spsc_atomic<T, Memory_Model>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename etl::ibip_buffer_spsc_atomic<T, MEMORY_MODEL> base_t;
|
||||
typedef typename etl::ibip_buffer_spsc_atomic<T, Memory_Model> base_t;
|
||||
|
||||
public:
|
||||
|
||||
@ -502,19 +502,19 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
static ETL_CONSTANT size_type RESERVED_SIZE = size_type(SIZE);
|
||||
static ETL_CONSTANT size_type Reserved_Size = size_type(Size);
|
||||
|
||||
public:
|
||||
|
||||
ETL_STATIC_ASSERT((SIZE <= (etl::integral_limits<size_type>::max)), "Size too large for memory model");
|
||||
ETL_STATIC_ASSERT((Size <= (etl::integral_limits<size_type>::max)), "Size too large for memory model");
|
||||
|
||||
static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE);
|
||||
static ETL_CONSTANT size_type MAX_SIZE = size_type(Size);
|
||||
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
bip_buffer_spsc_atomic()
|
||||
: base_t(reinterpret_cast<T*>(buffer.raw), RESERVED_SIZE)
|
||||
: base_t(reinterpret_cast<T*>(buffer.raw), Reserved_Size)
|
||||
{
|
||||
}
|
||||
|
||||
@ -529,11 +529,11 @@ namespace etl
|
||||
private:
|
||||
|
||||
/// The uninitialised buffer of T used in the bip_buffer_spsc.
|
||||
etl::uninitialized_buffer_of<T, RESERVED_SIZE> buffer;
|
||||
etl::uninitialized_buffer_of<T, Reserved_Size> buffer;
|
||||
};
|
||||
|
||||
template <typename T, const size_t SIZE, const size_t MEMORY_MODEL>
|
||||
ETL_CONSTANT typename bip_buffer_spsc_atomic<T, SIZE, MEMORY_MODEL>::size_type bip_buffer_spsc_atomic<T, SIZE, MEMORY_MODEL>::RESERVED_SIZE;
|
||||
template <typename T, const size_t Size, const size_t Memory_Model>
|
||||
ETL_CONSTANT typename bip_buffer_spsc_atomic<T, Size, Memory_Model>::size_type bip_buffer_spsc_atomic<T, Size, Memory_Model>::Reserved_Size;
|
||||
}
|
||||
|
||||
#endif /* ETL_HAS_ATOMIC && ETL_USING_CPP11 */
|
||||
|
||||
@ -236,8 +236,8 @@ namespace etl
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
|
||||
typedef typename etl::make_unsigned<T>::type chunk_t;
|
||||
|
||||
typedef typename etl::make_unsigned<T>::type chunk_t;
|
||||
chunk_t chunk = get_chunk(mask_width);
|
||||
|
||||
nbits -= mask_width;
|
||||
@ -529,7 +529,7 @@ namespace etl
|
||||
|
||||
typedef char value_type;
|
||||
typedef value_type* iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef etl::span<value_type> callback_parameter_type;
|
||||
typedef etl::delegate<void(callback_parameter_type)> callback_type;
|
||||
|
||||
|
||||
@ -251,7 +251,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
reference operator [](size_t index)
|
||||
{
|
||||
return pbuffer[(current + index) % picb->buffer_size];
|
||||
return picb->pbuffer[(current + index) % picb->buffer_size];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -259,7 +259,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_reference operator [](size_t index) const
|
||||
{
|
||||
return pbuffer[(current + index) % picb->buffer_size];
|
||||
return picb->pbuffer[(current + index) % picb->buffer_size];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -438,7 +438,7 @@ namespace etl
|
||||
//***************************************************
|
||||
pointer get_buffer() const
|
||||
{
|
||||
return pbuffer;
|
||||
return picb->pbuffer;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -550,7 +550,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
const_reference operator [](size_t index) const
|
||||
{
|
||||
return pbuffer[(current + index) % picb->buffer_size];
|
||||
return picb->pbuffer[(current + index) % picb->buffer_size];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -717,7 +717,7 @@ namespace etl
|
||||
//***************************************************
|
||||
pointer get_buffer() const
|
||||
{
|
||||
return pbuffer;
|
||||
return picb->pbuffer;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@ -52,19 +52,19 @@ namespace etl
|
||||
};
|
||||
|
||||
//*********************************
|
||||
value_type initial() const
|
||||
ETL_CONSTEXPR14 value_type initial() const
|
||||
{
|
||||
return even_parity;
|
||||
}
|
||||
|
||||
//*********************************
|
||||
uint8_t add(int parity, uint8_t value) const
|
||||
ETL_CONSTEXPR14 uint8_t add(int parity, uint8_t value) const
|
||||
{
|
||||
return parity ^ etl::parity(value);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
uint8_t final(uint8_t parity) const
|
||||
ETL_CONSTEXPR14 uint8_t final(uint8_t parity) const
|
||||
{
|
||||
return parity;
|
||||
}
|
||||
@ -83,7 +83,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
crc1()
|
||||
ETL_CONSTEXPR14 crc1()
|
||||
{
|
||||
this->reset();
|
||||
}
|
||||
@ -94,7 +94,7 @@ namespace etl
|
||||
/// \param end End of the range.
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
crc1(TIterator begin, const TIterator end)
|
||||
ETL_CONSTEXPR14 crc1(TIterator begin, const TIterator end)
|
||||
{
|
||||
this->reset();
|
||||
this->add(begin, end);
|
||||
|
||||
@ -158,23 +158,16 @@ inline void swap(etl::debug_count& lhs, etl::debug_count& rhs)
|
||||
}
|
||||
|
||||
#else
|
||||
#define ETL_DECLARE_DEBUG_COUNT etl::debug_count etl_debug_count
|
||||
#define ETL_SET_DEBUG_COUNT(n) ETL_DO_NOTHING
|
||||
#define ETL_GET_DEBUG_COUNT ETL_DO_NOTHING
|
||||
#define ETL_INCREMENT_DEBUG_COUNT ETL_DO_NOTHING
|
||||
#define ETL_DECREMENT_DEBUG_COUNT ETL_DO_NOTHING
|
||||
#define ETL_ADD_DEBUG_COUNT(n) ETL_DO_NOTHING
|
||||
#define ETL_SUBTRACT_DEBUG_COUNT(n) ETL_DO_NOTHING
|
||||
#define ETL_RESET_DEBUG_COUNT ETL_DO_NOTHING
|
||||
#define ETL_OBJECT_RESET_DEBUG_COUNT(object) ETL_DO_NOTHING
|
||||
#define ETL_OBJECT_GET_DEBUG_COUNT(object) ETL_DO_NOTHING
|
||||
|
||||
namespace etl
|
||||
{
|
||||
class debug_count
|
||||
{
|
||||
};
|
||||
}
|
||||
#define ETL_DECLARE_DEBUG_COUNT
|
||||
#define ETL_SET_DEBUG_COUNT(n)
|
||||
#define ETL_GET_DEBUG_COUNT
|
||||
#define ETL_INCREMENT_DEBUG_COUNT
|
||||
#define ETL_DECREMENT_DEBUG_COUNT
|
||||
#define ETL_ADD_DEBUG_COUNT(n)
|
||||
#define ETL_SUBTRACT_DEBUG_COUNT(n)
|
||||
#define ETL_RESET_DEBUG_COUNT
|
||||
#define ETL_OBJECT_RESET_DEBUG_COUNT(object)
|
||||
#define ETL_OBJECT_GET_DEBUG_COUNT(object)
|
||||
#endif // ETL_DEBUG_COUNT
|
||||
|
||||
#endif
|
||||
|
||||
@ -255,6 +255,38 @@ namespace etl
|
||||
}
|
||||
};
|
||||
}
|
||||
#elif defined(ETL_USE_ASSERT_FUNCTION)
|
||||
namespace etl
|
||||
{
|
||||
namespace private_error_handler
|
||||
{
|
||||
typedef void(*assert_function_ptr_t)(const etl::exception&);
|
||||
|
||||
// Stores the assert function pointer and default assert function.
|
||||
template <size_t N>
|
||||
struct assert_handler
|
||||
{
|
||||
static assert_function_ptr_t assert_function_ptr;
|
||||
|
||||
static void default_assert(const etl::exception&)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
assert_function_ptr_t assert_handler<N>::assert_function_ptr = assert_handler<N>::default_assert;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Sets the assert function.
|
||||
/// The argument function signature is void(*)(const etl::exception&)
|
||||
//***************************************************************************
|
||||
void set_assert_function(etl::private_error_handler::assert_function_ptr_t afptr)
|
||||
{
|
||||
etl::private_error_handler::assert_handler<0>::assert_function_ptr = afptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
@ -264,6 +296,7 @@ namespace etl
|
||||
/// If ETL_NO_CHECKS is defined then no runtime checks are executed at all.
|
||||
/// If asserts or exceptions are enabled then the error is thrown if the assert fails. The return value is always 'true'.
|
||||
/// If ETL_LOG_ERRORS is defined then the error is logged if the assert fails. The return value is the value of the boolean test.
|
||||
/// If ETL_USE_ASSERT_FUNCTION is defined then the error is sent to the assert function.
|
||||
/// Otherwise 'assert' is called. The return value is always 'true'.
|
||||
///\ingroup error_handler
|
||||
//***************************************************************************
|
||||
@ -275,6 +308,14 @@ namespace etl
|
||||
#define ETL_ASSERT_FAIL(e) ETL_DO_NOTHING // Does nothing.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN(e) ETL_DO_NOTHING // Does nothing.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) ETL_DO_NOTHING // Does nothing.
|
||||
#elif defined(ETL_USE_ASSERT_FUNCTION)
|
||||
#define ETL_ASSERT(b, e) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));}} // If the condition fails, calls the assert function
|
||||
#define ETL_ASSERT_OR_RETURN(b, e) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;}} // If the condition fails, calls the assert function and return
|
||||
#define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if(!(b)) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);}} // If the condition fails, calls the assert function and return a value
|
||||
|
||||
#define ETL_ASSERT_FAIL(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));} // Calls the assert function
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;} // Calls the assert function and return
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);} // Calls the assert function and return a value
|
||||
#elif ETL_USING_EXCEPTIONS
|
||||
#if defined(ETL_LOG_ERRORS)
|
||||
#define ETL_ASSERT(b, e) {if (!(b)) {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception.
|
||||
@ -292,7 +333,6 @@ namespace etl
|
||||
#define ETL_ASSERT_FAIL(e) {throw((e));} // Throws an exception.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN(e) {throw((e));} // Throws an exception.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {throw((e));} // Throws an exception.
|
||||
|
||||
#endif
|
||||
#else
|
||||
#if defined(ETL_LOG_ERRORS)
|
||||
@ -314,8 +354,8 @@ namespace etl
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {assert(false); return(v);} // Asserts.
|
||||
#else
|
||||
#define ETL_ASSERT(b, e) // Does nothing.
|
||||
#define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) return;} // Returns.
|
||||
#define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) return(v);} // Returns a value.
|
||||
#define ETL_ASSERT_OR_RETURN(b, e) {if (!(b)) return;} // Returns.
|
||||
#define ETL_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) return(v);} // Returns a value.
|
||||
|
||||
#define ETL_ASSERT_FAIL(e) // Does nothing.
|
||||
#define ETL_ASSERT_FAIL_AND_RETURN(e) {return;} // Returns.
|
||||
|
||||
@ -188,7 +188,7 @@ namespace etl
|
||||
|
||||
//*******************************************
|
||||
/// Get the error.
|
||||
//*******************************************
|
||||
//*******************************************
|
||||
ETL_CONSTEXPR14 TError&& error() const&& ETL_NOEXCEPT
|
||||
{
|
||||
return etl::move(error_value);
|
||||
@ -350,7 +350,7 @@ namespace etl
|
||||
//*******************************************
|
||||
template <typename... Args>
|
||||
ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args)
|
||||
: storage(etl::forward<Args>(args)...)
|
||||
: storage(etl::in_place_index_t<Value_Type>(), etl::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
|
||||
@ -360,7 +360,7 @@ namespace etl
|
||||
//*******************************************
|
||||
template <typename U, typename... Args>
|
||||
ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list<U> il, Args&&... args)
|
||||
: storage(il, etl::forward<Args>(args)...)
|
||||
: storage(etl::in_place_index_t<Value_Type>(), il, etl::forward<Args>(args)...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -500,7 +500,7 @@ namespace etl
|
||||
//*******************************************
|
||||
/// Get the value.
|
||||
//*******************************************
|
||||
value_type& value() const
|
||||
const value_type& value() const
|
||||
{
|
||||
return etl::get<Value_Type>(storage);
|
||||
}
|
||||
@ -511,7 +511,7 @@ namespace etl
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
bool has_value() const
|
||||
bool has_value() const ETL_NOEXCEPT
|
||||
{
|
||||
return (storage.index() == Value_Type);
|
||||
}
|
||||
@ -521,7 +521,8 @@ namespace etl
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
operator bool() const
|
||||
ETL_EXPLICIT
|
||||
operator bool() const ETL_NOEXCEPT
|
||||
{
|
||||
return has_value();
|
||||
}
|
||||
@ -659,7 +660,7 @@ namespace etl
|
||||
//*******************************************
|
||||
///
|
||||
//*******************************************
|
||||
error_type& error() const
|
||||
const error_type& error() const
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
@ -865,8 +866,8 @@ namespace etl
|
||||
/// Returns true if expected has a value
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
bool has_value() const
|
||||
ETL_CONSTEXPR14
|
||||
bool has_value() const ETL_NOEXCEPT
|
||||
{
|
||||
return (storage.index() != Error_Type);
|
||||
}
|
||||
@ -875,8 +876,9 @@ namespace etl
|
||||
/// Returns true if expected has a value
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
operator bool() const
|
||||
ETL_CONSTEXPR14
|
||||
ETL_EXPLICIT
|
||||
operator bool() const ETL_NOEXCEPT
|
||||
{
|
||||
return has_value();
|
||||
}
|
||||
@ -887,8 +889,8 @@ namespace etl
|
||||
/// Undefined behaviour if an error has not been set.
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
error_type& error()& ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14
|
||||
error_type& error()& ETL_NOEXCEPT
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
@ -898,8 +900,8 @@ namespace etl
|
||||
/// Undefined behaviour if an error has not been set.
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
const error_type& error() const& ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14
|
||||
const error_type& error() const& ETL_NOEXCEPT
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
@ -909,8 +911,8 @@ namespace etl
|
||||
/// Undefined behaviour if an error has not been set.
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
error_type&& error() && ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14
|
||||
error_type&& error() && ETL_NOEXCEPT
|
||||
{
|
||||
return etl::move(etl::get<Error_Type>(storage));
|
||||
}
|
||||
@ -920,8 +922,8 @@ namespace etl
|
||||
/// Undefined behaviour if an error has not been set.
|
||||
//*******************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
const error_type&& error() const&& ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR14
|
||||
const error_type&& error() const&& ETL_NOEXCEPT
|
||||
{
|
||||
return etl::move(etl::get<Error_Type>(storage));
|
||||
}
|
||||
@ -930,7 +932,7 @@ namespace etl
|
||||
/// Returns the error
|
||||
/// Undefined behaviour if an error has not been set.
|
||||
//*******************************************
|
||||
error_type& error() const
|
||||
const error_type& error() const
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
@ -1105,4 +1107,3 @@ void swap(etl::unexpected<TError>& lhs, etl::unexpected<TError>& rhs)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -103,5 +103,8 @@ SOFTWARE.
|
||||
#define ETL_EXPECTED_FILE_ID "70"
|
||||
#define ETL_ALIGNMENT_FILE_ID "71"
|
||||
#define ETL_BASE64_FILE_ID "72"
|
||||
#define ETL_SINGLETON_BASE_FILE_ID "73"
|
||||
#define ETL_UNALIGNED_TYPE_FILE_ID "74"
|
||||
#define ETL_SPAN_FILE_ID "75"
|
||||
|
||||
#endif
|
||||
|
||||
@ -107,7 +107,8 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
frame_check_sequence()
|
||||
ETL_CONSTEXPR14 frame_check_sequence()
|
||||
: frame_check()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
@ -118,7 +119,7 @@ namespace etl
|
||||
/// \param end End of the range.
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
frame_check_sequence(TIterator begin, const TIterator end)
|
||||
ETL_CONSTEXPR14 frame_check_sequence(TIterator begin, const TIterator end) : frame_check()
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(typename etl::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
@ -129,7 +130,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Resets the FCS to the initial state.
|
||||
//*************************************************************************
|
||||
void reset()
|
||||
ETL_CONSTEXPR14 void reset()
|
||||
{
|
||||
frame_check = policy.initial();
|
||||
}
|
||||
@ -140,7 +141,7 @@ namespace etl
|
||||
/// \param end
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
void add(TIterator begin, const TIterator end)
|
||||
ETL_CONSTEXPR14 void add(TIterator begin, const TIterator end)
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(typename etl::iterator_traits<TIterator>::value_type) == 1, "Type not supported");
|
||||
|
||||
@ -154,7 +155,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// \param value The uint8_t to add to the FCS.
|
||||
//*************************************************************************
|
||||
void add(uint8_t value_)
|
||||
ETL_CONSTEXPR14 void add(uint8_t value_)
|
||||
{
|
||||
frame_check = policy.add(frame_check, value_);
|
||||
}
|
||||
@ -162,7 +163,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets the FCS value.
|
||||
//*************************************************************************
|
||||
value_type value() const
|
||||
ETL_CONSTEXPR14 value_type value() const
|
||||
{
|
||||
return policy.final(frame_check);
|
||||
}
|
||||
@ -170,7 +171,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Conversion operator to value_type.
|
||||
//*************************************************************************
|
||||
operator value_type () const
|
||||
ETL_CONSTEXPR14 operator value_type () const
|
||||
{
|
||||
return policy.final(frame_check);
|
||||
}
|
||||
@ -178,7 +179,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Gets an add_insert_iterator for input.
|
||||
//*************************************************************************
|
||||
add_insert_iterator input()
|
||||
ETL_CONSTEXPR14 add_insert_iterator input()
|
||||
{
|
||||
return add_insert_iterator(*this);
|
||||
}
|
||||
|
||||
136
include/etl/function_traits.h
Normal file
136
include/etl/function_traits.h
Normal file
@ -0,0 +1,136 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 John Wellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_FUNCTION_TRAITS_INCLUDED
|
||||
#define ETL_FUNCTION_TRAITS_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "type_list.h"
|
||||
#include "type_traits.h"
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// A template to extract the function type traits.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct function_traits;
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename... TArgs>
|
||||
struct function_traits<TReturn(*)(TArgs...)>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = void; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
|
||||
static constexpr bool is_function = true; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = false; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = false; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
};
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_const;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(*)(TArgs...)>::argument_count;
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = TObject; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
|
||||
static constexpr bool is_function = false; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = true; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = false; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_const;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(TObject::*)(TArgs...)>::argument_count;
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for const member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn(TObject::*)(TArgs...) const>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = TObject; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
|
||||
static constexpr bool is_function = false; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = true; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = true; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_const;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(TObject::*)(TArgs...) const>::argument_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -112,6 +112,39 @@ namespace etl
|
||||
return reference_wrapper<const T>(t.get());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// unwrap_reference.
|
||||
//***************************************************************************
|
||||
template <class T>
|
||||
struct unwrap_reference
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unwrap_reference<etl::reference_wrapper<T> >
|
||||
{
|
||||
typedef T& type;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename T>
|
||||
using unwrap_reference_t = typename unwrap_reference<T>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// unwrap_ref_decay.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct unwrap_ref_decay : etl::unwrap_reference<typename etl::decay<T>::type> {};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename T>
|
||||
using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// unary_function
|
||||
//***************************************************************************
|
||||
template <typename TArgumentType, typename TResultType>
|
||||
struct unary_function
|
||||
@ -120,6 +153,8 @@ namespace etl
|
||||
typedef TResultType result_type;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// binary_function
|
||||
//***************************************************************************
|
||||
template <typename TFirstArgumentType, typename TSecondArgumentType, typename TResultType>
|
||||
struct binary_function
|
||||
|
||||
@ -65,8 +65,6 @@ cog.outl("//********************************************************************
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
|
||||
#include "message.h"
|
||||
#include "error_handler.h"
|
||||
#include "static_assert.h"
|
||||
@ -298,11 +296,39 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
#if !ETL_HAS_VIRTUAL_MESSAGES
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
(delete_message_type<TMessageTypes>(pmsg) || ...);
|
||||
}
|
||||
|
||||
//********************************************
|
||||
template <typename TType>
|
||||
bool delete_message_type(etl::imessage* pmsg)
|
||||
{
|
||||
if (TType::ID == pmsg->get_message_id())
|
||||
{
|
||||
TType* p = static_cast<TType*>(pmsg);
|
||||
p->~TType();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -671,12 +697,28 @@ namespace etl
|
||||
cog.outl(" {")
|
||||
cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
|
||||
cog.outl("")
|
||||
cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
|
||||
cog.outl(" pmsg->~imessage();")
|
||||
cog.outl("#else")
|
||||
cog.outl(" delete_message(pmsg);")
|
||||
cog.outl("#endif")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl(" #include \"private/diagnostic_pop.h\"")
|
||||
cog.outl("")
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void delete_message(etl::imessage* pmsg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" switch (pmsg->get_message_id())")
|
||||
cog.outl(" {")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.out(" case T%d::ID: static_cast<const T%d" %(n, n))
|
||||
cog.outl("*>(pmsg)->~T%d(); break;" % n)
|
||||
cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
@ -686,7 +728,7 @@ namespace etl
|
||||
cog.outl(" {")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(n, n, n))
|
||||
cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
@ -701,7 +743,7 @@ namespace etl
|
||||
cog.outl(" {")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<T%d&&>(msg)); break;" %(n, n, n))
|
||||
cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("#endif")
|
||||
@ -959,12 +1001,29 @@ namespace etl
|
||||
cog.outl(" {")
|
||||
cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
|
||||
cog.outl("")
|
||||
cog.outl("")
|
||||
cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
|
||||
cog.outl(" pmsg->~imessage();")
|
||||
cog.outl("#else")
|
||||
cog.outl(" delete_message(pmsg);")
|
||||
cog.outl("#endif")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl(" #include \"private/diagnostic_pop.h\"")
|
||||
cog.outl("")
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void delete_message(etl::imessage* pmsg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" switch (pmsg->get_message_id())")
|
||||
cog.outl(" {")
|
||||
for t in range(1, n + 1):
|
||||
cog.out(" case T%d::ID: static_cast<const T%d" %(t, t))
|
||||
cog.outl("*>(pmsg)->~T%d(); break;" % t)
|
||||
cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" //********************************************")
|
||||
cog.outl(" void add_new_message(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" const size_t id = msg.get_message_id();")
|
||||
@ -974,7 +1033,7 @@ namespace etl
|
||||
cog.outl(" {")
|
||||
for t in range(1, n + 1):
|
||||
cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(t, t, t))
|
||||
cog.outl(" default: break;")
|
||||
cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
@ -1001,8 +1060,5 @@ namespace etl
|
||||
/*[[[end]]]*/
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#error "etl::message_packet is not compatible with non-virtual etl::imessage"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -66,9 +66,7 @@ cog.outl("//********************************************************************
|
||||
#include "platform.h"
|
||||
#include "message.h"
|
||||
#include "shared_message.h"
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
#include "message_packet.h"
|
||||
#endif
|
||||
#include "message_packet.h"
|
||||
#include "message_types.h"
|
||||
#include "alignment.h"
|
||||
#include "error_handler.h"
|
||||
@ -424,9 +422,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<TMessageTypes...> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router()
|
||||
@ -584,12 +580,10 @@ namespace etl
|
||||
cog.outl("{")
|
||||
cog.outl("public:")
|
||||
cog.outl("")
|
||||
cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
|
||||
cog.out(" typedef etl::message_packet<")
|
||||
for n in range(1, int(Handlers)):
|
||||
cog.out("T%s, " % n)
|
||||
cog.outl(" T%s> message_packet;" % int(Handlers))
|
||||
cog.outl("#endif")
|
||||
cog.outl("")
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" message_router(etl::message_router_id_t id_)")
|
||||
@ -754,12 +748,10 @@ namespace etl
|
||||
cog.outl("{")
|
||||
cog.outl("public:")
|
||||
cog.outl("")
|
||||
cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
|
||||
cog.out(" typedef etl::message_packet<")
|
||||
for t in range(1, n):
|
||||
cog.out("T%s, " % t)
|
||||
cog.outl(" T%s> message_packet;" % n)
|
||||
cog.outl("#endif")
|
||||
cog.outl("")
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" message_router(etl::message_router_id_t id_)")
|
||||
|
||||
@ -640,17 +640,12 @@ namespace etl
|
||||
{
|
||||
private:
|
||||
|
||||
template<typename T> struct dummy {};
|
||||
struct internal: TDerived, dummy<int>{};
|
||||
|
||||
static TBase* check(TBase*) { return (TBase*)0; }
|
||||
|
||||
template<typename T>
|
||||
static char check(dummy<T>*) { return 0; }
|
||||
static char check(...) { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*));
|
||||
static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
|
||||
};
|
||||
|
||||
// For when TBase or TDerived is a fundamental type.
|
||||
@ -1339,6 +1334,79 @@ typedef integral_constant<bool, true> true_type;
|
||||
// ETL extended type traits.
|
||||
//***************************************************************************
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// conjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct conjunction : public etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct conjunction<T> : public T
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool conjunction_v = conjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct disjunction : public etl::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1> struct disjunction<T1> : public T1
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// exclusive_disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename... TTypes>
|
||||
struct exclusive_disjunction;
|
||||
|
||||
template <typename T>
|
||||
struct exclusive_disjunction<T> : public etl::bool_constant<T::value>
|
||||
{
|
||||
};
|
||||
|
||||
// Recursive case: XOR the first two values and recurse
|
||||
template <typename T1, typename T2, typename... TRest>
|
||||
struct exclusive_disjunction<T1, T2, TRest...> : public etl::exclusive_disjunction<etl::integral_constant<bool, etl::disjunction<T1, T2>::value && !etl::conjunction<T1, T2>::value>, TRest...>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// conditional_integral_constant
|
||||
// /\ingroup type_traits
|
||||
@ -1361,19 +1429,11 @@ typedef integral_constant<bool, true> true_type;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is one of a specified list.
|
||||
/// Template to determine if a type is a base of all types in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_one_of
|
||||
template <typename T, typename... TRest>
|
||||
struct is_one_of : etl::disjunction<etl::is_same<T, TRest>...>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value ||
|
||||
etl::is_one_of<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_one_of<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value;
|
||||
};
|
||||
#else
|
||||
/*[[[cog
|
||||
@ -1406,21 +1466,46 @@ typedef integral_constant<bool, true> true_type;
|
||||
inline constexpr bool is_one_of_v = etl::is_one_of<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace private_type_traits
|
||||
{
|
||||
//***************************************************************************
|
||||
// Helper to count occurrences of a type in a list of types
|
||||
template<typename T, typename... TTypes>
|
||||
struct count_type;
|
||||
|
||||
// Base case: zero occurrences
|
||||
template<typename T>
|
||||
struct count_type<T> : etl::integral_constant<size_t, 0>
|
||||
{
|
||||
};
|
||||
|
||||
// Recursive case: increment count if head is the same as T, otherwise continue with tail
|
||||
template<typename T, typename THead, typename... TTail>
|
||||
struct count_type<T, THead, TTail...> : etl::integral_constant<size_t, (etl::is_same<T, THead>::value ? 1 : 0) + count_type<T, TTail...>::value>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, typename... TTypes>
|
||||
struct has_duplicates_of
|
||||
: etl::integral_constant<bool, (private_type_traits::count_type<T, TTypes...>::value > 1)>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename... TRest>
|
||||
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is a base of all types in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_base_of_all
|
||||
template <typename TBase, typename... TDerived>
|
||||
struct is_base_of_all : etl::conjunction<etl::is_base_of<TBase, TDerived>...>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value &&
|
||||
etl::is_base_of_all<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_base_of_all<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1433,18 +1518,11 @@ typedef integral_constant<bool, true> true_type;
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is a base of any type in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_base_of_any
|
||||
template <typename TBase, typename... TDerived>
|
||||
struct is_base_of_any : etl::disjunction<etl::is_base_of<TBase, TDerived>...>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value ||
|
||||
etl::is_base_of_any<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_base_of_any<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
@ -1452,6 +1530,28 @@ typedef integral_constant<bool, true> true_type;
|
||||
inline constexpr bool is_base_of_any_v = etl::is_base_of_any<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Get the Nth base of a recursively inherited type.
|
||||
/// Requires that the class has defined 'base_type'.
|
||||
//***************************************************************************
|
||||
// Recursive definition of the type.
|
||||
template <size_t N, typename TType>
|
||||
struct nth_base
|
||||
{
|
||||
typedef typename nth_base<N - 1U, typename TType::base_type>::type type;
|
||||
};
|
||||
|
||||
template <typename TType>
|
||||
struct nth_base<0, TType>
|
||||
{
|
||||
typedef TType type;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <size_t N, typename TType>
|
||||
using nth_base_t = typename nth_base<N, TType>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// A set of templates to allow related types to be derived.
|
||||
///\ingroup types
|
||||
@ -1605,70 +1705,15 @@ typedef integral_constant<bool, true> true_type;
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// are_all_same
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct are_all_same
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value &&
|
||||
etl::are_all_same<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct are_all_same<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
inline constexpr bool are_all_same_v = are_all_same<T, T1, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// conjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct conjunction : public etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct conjunction<T> : public T
|
||||
template <typename T, typename... TRest>
|
||||
struct are_all_same : etl::conjunction<etl::is_same<T, TRest>...>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool conjunction_v = conjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct disjunction : public etl::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1> struct disjunction<T1> : public T1
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
|
||||
template <typename T, typename... TRest>
|
||||
inline constexpr bool are_all_same_v = are_all_same<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
@ -2318,6 +2363,9 @@ typedef integral_constant<bool, true> true_type;
|
||||
etl::true_type,
|
||||
has_duplicates<TRest...>> {};
|
||||
|
||||
template <typename T>
|
||||
struct has_duplicates<T> : etl::false_type {};
|
||||
|
||||
template <>
|
||||
struct has_duplicates<> : etl::false_type {};
|
||||
#endif
|
||||
@ -2346,18 +2394,6 @@ typedef integral_constant<bool, true> true_type;
|
||||
template <typename T, typename... TTypes>
|
||||
inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************
|
||||
// has_duplicates_of
|
||||
template <typename T, typename... TTypes>
|
||||
struct has_duplicates_of : etl::bool_constant<(etl::count_of<T, TTypes...>::value > 1U)> {};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename... TTypes>
|
||||
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TTypes...>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper macros
|
||||
|
||||
80
include/etl/index_of_type.h
Normal file
80
include/etl/index_of_type.h
Normal file
@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 John Wellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_INDEX_OF_TYPE_INCLUDED
|
||||
#define ETL_INDEX_OF_TYPE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "static_assert.h"
|
||||
#include "integral_limits.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines a no-position constant.
|
||||
//***************************************************************************
|
||||
static ETL_CONSTANT size_t index_of_type_npos = etl::integral_limits<size_t>::max;
|
||||
|
||||
//***************************************************************************
|
||||
/// Finds the index of a type in a variadic type parameter.
|
||||
//***************************************************************************
|
||||
template <typename T, typename... TTypes>
|
||||
struct index_of_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Finds the index of a type in a variadic type parameter.
|
||||
//***************************************************************************
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct index_of_type<T, T1, TRest...> : public etl::integral_constant<size_t, etl::is_same<T, T1>::value ? 0 :
|
||||
(etl::index_of_type<T, TRest...>::value == etl::index_of_type_npos ? etl::index_of_type_npos :
|
||||
etl::index_of_type<T, TRest...>::value + 1)>
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Finds the index of a type in a variadic type parameter.
|
||||
/// No types left.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct index_of_type<T> : public etl::integral_constant<size_t, etl::index_of_type_npos>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//***************************************************************************
|
||||
/// Finds the index of a type in a variadic type parameter.
|
||||
//***************************************************************************
|
||||
template <typename T, typename... TTypes>
|
||||
inline constexpr size_t index_of_type_v = etl::index_of_type<T, TTypes...>::value;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -253,6 +253,24 @@ namespace etl
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified node in list.
|
||||
///\param search_link The node to find in list
|
||||
//*************************************************************************
|
||||
bool contains_node(const link_type& search_link) const
|
||||
{
|
||||
return is_link_in_list(&search_link);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified node in list.
|
||||
///\param search_link The node to find in list
|
||||
//*************************************************************************
|
||||
bool contains_node(const link_type* search_link) const
|
||||
{
|
||||
return is_link_in_list(search_link);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
link_type start; ///< The link pointer that acts as the intrusive_forward_list start.
|
||||
@ -304,7 +322,10 @@ namespace etl
|
||||
if (p_next != &this->terminator)
|
||||
{
|
||||
link_type* p_unlinked = etl::unlink_after<link_type>(link);
|
||||
p_unlinked->clear();
|
||||
if (p_unlinked != ETL_NULLPTR)
|
||||
{
|
||||
p_unlinked->clear();
|
||||
}
|
||||
--current_size;
|
||||
}
|
||||
}
|
||||
@ -338,24 +359,20 @@ namespace etl
|
||||
/// Tests if the link is in this list.
|
||||
/// Returns the previous link to it, if found, otherwise ETL_NULLPTR.
|
||||
//*************************************************************************
|
||||
link_type* is_link_in_list(link_type& search_link)
|
||||
link_type* is_link_in_list(const link_type* search_link) const
|
||||
{
|
||||
link_type* p_link = start.etl_next;
|
||||
link_type* p_previous = &start;
|
||||
link_type* p_previous = const_cast<link_type*>(&start);
|
||||
|
||||
while (p_link != ETL_NULLPTR)
|
||||
{
|
||||
if (&search_link == p_link)
|
||||
if (search_link == p_link)
|
||||
{
|
||||
return p_previous;
|
||||
}
|
||||
|
||||
p_previous = p_link;
|
||||
|
||||
if (p_link != ETL_NULLPTR)
|
||||
{
|
||||
p_link = p_link->link_type::etl_next;
|
||||
}
|
||||
p_link = p_link->link_type::etl_next;
|
||||
}
|
||||
|
||||
return ETL_NULLPTR;
|
||||
@ -366,7 +383,7 @@ namespace etl
|
||||
/// Returns ETL_NULLPTR if the link was not in this list.
|
||||
/// Returns the next
|
||||
//*************************************************************************
|
||||
link_type* remove_link(link_type& link)
|
||||
link_type* remove_link(link_type* link)
|
||||
{
|
||||
link_type* result = ETL_NULLPTR;
|
||||
|
||||
@ -374,7 +391,7 @@ namespace etl
|
||||
|
||||
if (p_previous != ETL_NULLPTR)
|
||||
{
|
||||
link_type* p_next = link.etl_next;
|
||||
link_type* p_next = link->etl_next;
|
||||
|
||||
disconnect_link_after(*p_previous);
|
||||
|
||||
@ -629,6 +646,22 @@ namespace etl
|
||||
this->assign(first, last);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Constructor from variadic list of nodes.
|
||||
//*************************************************************************
|
||||
template <typename... TLinks>
|
||||
intrusive_forward_list(link_type& first, TLinks&... links)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of_all<link_type, TLinks...>::value), "Mixed link types");
|
||||
|
||||
this->current_size = 0;
|
||||
this->start.etl_next = &first;
|
||||
link_type* last = make_linked_list(this->current_size, first, static_cast<link_type&>(links)...);
|
||||
last->etl_next = &this->terminator;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the beginning of the intrusive_forward_list.
|
||||
//*************************************************************************
|
||||
@ -787,9 +820,17 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Erases the specified node.
|
||||
//*************************************************************************
|
||||
node_type* erase(node_type& node)
|
||||
node_type* erase(const node_type& node)
|
||||
{
|
||||
return static_cast<node_type*>(this->remove_link(node));
|
||||
return static_cast<node_type*>(this->remove_link(const_cast<node_type*>(&node)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases the specified node.
|
||||
//*************************************************************************
|
||||
node_type* erase(const node_type* p_node)
|
||||
{
|
||||
return static_cast<node_type*>(this->remove_link(const_cast<node_type*>(p_node)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -991,6 +1032,29 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Removes the element specified by pointer.
|
||||
//*************************************************************************
|
||||
void remove(const_pointer element)
|
||||
{
|
||||
iterator i_item = begin();
|
||||
iterator i_last_item = before_begin();
|
||||
|
||||
while (i_item != end())
|
||||
{
|
||||
if (&i_item == element)
|
||||
{
|
||||
i_item = erase_after(i_last_item);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
++i_item;
|
||||
++i_last_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes according to a predicate.
|
||||
//*************************************************************************
|
||||
@ -1167,8 +1231,64 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified value in list.
|
||||
///\param value The value to find in list
|
||||
//*************************************************************************
|
||||
bool contains(const_reference value) const
|
||||
{
|
||||
const_iterator i_item = begin();
|
||||
|
||||
while (i_item != end())
|
||||
{
|
||||
if (*i_item == value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
++i_item;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename... TLinks>
|
||||
link_type* make_linked_list(size_t& count, link_type& first, TLinks&... links)
|
||||
{
|
||||
link_type* current = &first;
|
||||
++count;
|
||||
((current->etl_next = &links, current = &links, ++count), ...);
|
||||
|
||||
return current;
|
||||
}
|
||||
#elif ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Create a counted linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
link_type* make_linked_list(size_t& count, link_type& first)
|
||||
{
|
||||
++count;
|
||||
return &first;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a counted linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename... TLinks>
|
||||
link_type* make_linked_list(size_t& count, link_type& first, link_type& next, TLinks&... links)
|
||||
{
|
||||
++count;
|
||||
first.etl_next = &next;
|
||||
return make_linked_list(count, next, static_cast<link_type&>(links)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the next value.
|
||||
//*************************************************************************
|
||||
|
||||
@ -375,7 +375,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// link_clear
|
||||
// link_clear range
|
||||
//***************************************************************************
|
||||
// Reference
|
||||
template <typename TLink>
|
||||
@ -404,6 +404,112 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first, TLinks&... links)
|
||||
{
|
||||
TLink* current = &first;
|
||||
((current->etl_next = &links, current = &links), ...);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink* first, TLinks*... links)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
return create_linked_list(*first, (*links)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
#elif ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first)
|
||||
{
|
||||
return &first;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first, TLink& next, TLinks&... links)
|
||||
{
|
||||
first.etl_next = &next;
|
||||
return create_linked_list(next, static_cast<TLink&>(links)...);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink* first)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
return create_linked_list(*first);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of forward_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink* first, TLink* next, TLinks*... links)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
return create_linked_list(*first, *next, static_cast<TLink&>(*links)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
|
||||
detach_linked_list(TLink& first)
|
||||
{
|
||||
link_clear_range(first);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_forward_link<TLink>::value, void>::type
|
||||
detach_linked_list(TLink* first)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
detach_linked_list(*first);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// A bidirectional link.
|
||||
//***************************************************************************
|
||||
@ -829,6 +935,93 @@ namespace etl
|
||||
etl::link_clear_range(*start);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first, TLinks&... links)
|
||||
{
|
||||
TLink* current = &first;
|
||||
((current->etl_next = &links, static_cast<TLink&>(links).etl_previous = current, current = &links), ...);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink* first, TLinks*... links)
|
||||
{
|
||||
TLink* current = first;
|
||||
((current->etl_next = links, static_cast<TLink*>(links)->etl_previous = current, current = links), ...);
|
||||
|
||||
return current;
|
||||
}
|
||||
#elif ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first)
|
||||
{
|
||||
return &first;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink& first, TLink& next, TLinks&... links)
|
||||
{
|
||||
first.etl_next = &next;
|
||||
next.etl_previous = &first;
|
||||
|
||||
return create_linked_list(next, static_cast<TLink&>(links)...);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename TLink, typename... TLinks>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, TLink*>::type
|
||||
create_linked_list(TLink* first, TLink* next, TLinks*... links)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
return create_linked_list(*first, *next, static_cast<TLink&>(*links)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, void>::type
|
||||
detach_linked_list(TLink& first)
|
||||
{
|
||||
link_clear_range(first);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
template <typename TLink>
|
||||
typename etl::enable_if<etl::is_bidirectional_link<TLink>::value, void>::type
|
||||
detach_linked_list(TLink* first)
|
||||
{
|
||||
if (first != ETL_NULLPTR)
|
||||
{
|
||||
detach_linked_list(*first);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// A binary tree link.
|
||||
//***************************************************************************
|
||||
|
||||
@ -255,6 +255,24 @@ namespace etl
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified node in list.
|
||||
///\param search_link The node to find in list
|
||||
//*************************************************************************
|
||||
bool contains_node(const link_type& search_link) const
|
||||
{
|
||||
return is_link_in_list(&search_link);;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified node in list.
|
||||
///\param search_link The node to find in list
|
||||
//*************************************************************************
|
||||
bool contains_node(const link_type* search_link) const
|
||||
{
|
||||
return is_link_in_list(search_link);;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// The link that acts as the intrusive_list start & end.
|
||||
@ -379,13 +397,13 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Tests if the link is in this list.
|
||||
//*************************************************************************
|
||||
bool is_link_in_list(link_type& search_link) const
|
||||
bool is_link_in_list(const link_type* search_link) const
|
||||
{
|
||||
link_type* p_link = terminal_link.link_type::etl_next;
|
||||
|
||||
while (p_link != &terminal_link)
|
||||
{
|
||||
if (&search_link == p_link)
|
||||
if (search_link == p_link)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -400,13 +418,13 @@ namespace etl
|
||||
/// Remove the specified node from the list.
|
||||
/// Returns ETL_NULLPTR if the link was not in this list or was the last in the list.
|
||||
//*************************************************************************
|
||||
link_type* remove_link(link_type& link)
|
||||
link_type* remove_link(link_type* link)
|
||||
{
|
||||
link_type* result = ETL_NULLPTR;
|
||||
|
||||
if (is_link_in_list(link))
|
||||
{
|
||||
link_type* p_next = link.etl_next;
|
||||
link_type* p_next = link->etl_next;
|
||||
|
||||
disconnect_link(link);
|
||||
|
||||
@ -685,6 +703,24 @@ namespace etl
|
||||
this->assign(first, last);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Constructor from variadic list of nodes.
|
||||
//*************************************************************************
|
||||
template <typename... TLinks>
|
||||
intrusive_list(link_type& first, TLinks&... links)
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of_all<link_type, TLinks...>::value), "Mixed link types");
|
||||
|
||||
this->current_size = 0;
|
||||
this->terminal_link.etl_next = &first;
|
||||
link_type* last = make_linked_list(this->current_size, first, static_cast<link_type&>(links)...);
|
||||
first.etl_previous = &this->terminal_link;
|
||||
last->etl_next = &this->terminal_link;
|
||||
this->terminal_link.etl_previous = last;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the beginning of the intrusive_list.
|
||||
//*************************************************************************
|
||||
@ -843,9 +879,17 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Erases the specified node.
|
||||
//*************************************************************************
|
||||
node_type* erase(node_type& node)
|
||||
node_type* erase(const node_type& node)
|
||||
{
|
||||
return static_cast<node_type*>(this->remove_link(node));
|
||||
return static_cast<node_type*>(this->remove_link(const_cast<node_type*>(&node)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Erases the specified node.
|
||||
//*************************************************************************
|
||||
node_type* erase(const node_type* p_node)
|
||||
{
|
||||
return static_cast<node_type*>(this->remove_link(const_cast<node_type*>(p_node)));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -1192,8 +1236,67 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detects existence of specified value in list.
|
||||
///\param value The value to find in list
|
||||
//*************************************************************************
|
||||
bool contains(const_reference value) const
|
||||
{
|
||||
const_iterator i_item = begin();
|
||||
|
||||
while (i_item != end())
|
||||
{
|
||||
if (*i_item == value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
++i_item;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename... TLinks>
|
||||
link_type* make_linked_list(size_t& count, link_type& first, TLinks&... links)
|
||||
{
|
||||
TLink* current = &first;
|
||||
++count;
|
||||
((current->etl_next = &links, static_cast<TLink&>(links).etl_previous = current, current = &links, ++count), ...);
|
||||
|
||||
return current;
|
||||
}
|
||||
#elif ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
link_type* make_linked_list(size_t& count, link_type& first)
|
||||
{
|
||||
++count;
|
||||
|
||||
return &first;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Create a linked list from a number of bidirectional_link nodes.
|
||||
//***************************************************************************
|
||||
template <typename... TLinks>
|
||||
link_type* make_linked_list(size_t& count, link_type& first, link_type& next, TLinks&... links)
|
||||
{
|
||||
++count;
|
||||
first.etl_next = &next;
|
||||
next.etl_previous = &first;
|
||||
|
||||
return make_linked_list(count, next, static_cast<link_type&>(links)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Disabled.
|
||||
intrusive_list(const intrusive_list& other);
|
||||
intrusive_list& operator = (const intrusive_list& rhs);
|
||||
|
||||
@ -271,6 +271,14 @@ namespace etl
|
||||
return Max_Size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum size of an item in the pool.
|
||||
//*************************************************************************
|
||||
size_t max_item_size() const
|
||||
{
|
||||
return Item_Size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
@ -377,39 +385,13 @@ namespace etl
|
||||
//*************************************************************************
|
||||
void release_item(char* p_value)
|
||||
{
|
||||
//// Does it belong to us?
|
||||
//ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool));
|
||||
|
||||
//if (p_next != ETL_NULLPTR)
|
||||
//{
|
||||
// // Point it to the current free item.
|
||||
// *(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // This is the only free item.
|
||||
// *((uintptr_t*)p_value) = 0;
|
||||
//}
|
||||
|
||||
//p_next = p_value;
|
||||
|
||||
//--items_allocated;
|
||||
|
||||
// Does it belong to us?
|
||||
ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool));
|
||||
|
||||
if (items_allocated > 0)
|
||||
{
|
||||
if (p_next != ETL_NULLPTR)
|
||||
{
|
||||
// Point it to the current free item.
|
||||
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the only free item.
|
||||
*((uintptr_t*)p_value) = 0;
|
||||
}
|
||||
// Point it to the current free item.
|
||||
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
|
||||
p_next = p_value;
|
||||
|
||||
|
||||
@ -139,7 +139,7 @@ namespace etl
|
||||
{
|
||||
ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large");
|
||||
|
||||
::new (static_cast<void*>(buffer)) T(value);
|
||||
::new (static_cast<void*>(buffer.raw)) T(value);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -148,7 +148,7 @@ namespace etl
|
||||
template <typename T>
|
||||
void assign_at_offset(size_t offset, const T& value)
|
||||
{
|
||||
char* p = static_cast<char*>(buffer) + offset;
|
||||
char* p = static_cast<char*>(buffer.raw) + offset;
|
||||
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
::new (p) T(value);
|
||||
@ -160,7 +160,7 @@ namespace etl
|
||||
template <typename T, size_t Offset>
|
||||
void assign_at_offset(const T& value)
|
||||
{
|
||||
char* p = static_cast<char*>(buffer) + Offset;
|
||||
char* p = static_cast<char*>(buffer.raw) + Offset;
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Type size is too large");
|
||||
|
||||
::new (p) T(value);
|
||||
@ -171,35 +171,41 @@ namespace etl
|
||||
/// Emplace from parameters
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace(TArgs... args)
|
||||
T& emplace(TArgs... args)
|
||||
{
|
||||
ETL_STATIC_ASSERT(Size >= sizeof(T), "Type size is too large");
|
||||
|
||||
::new (static_cast<void*>(buffer)) T(etl::forward<TArgs>(args)...);
|
||||
::new (static_cast<void*>(buffer.raw)) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref<T>();
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Emplace from parameters at offset
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace_at_offset(size_t offset, TArgs... args)
|
||||
T& emplace_at_offset(size_t offset, TArgs... args)
|
||||
{
|
||||
char* p = static_cast<char*>(buffer) + offset;
|
||||
char* p = static_cast<char*>(buffer.raw) + offset;
|
||||
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
::new (p) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref_at_offset<T>(offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Emplace from parameters at offset
|
||||
//***********************************
|
||||
template <typename T, size_t Offset, typename... TArgs>
|
||||
void emplace_at_offset(TArgs... args)
|
||||
T& emplace_at_offset(TArgs... args)
|
||||
{
|
||||
char* p = static_cast<char*>(buffer) + Offset;
|
||||
char* p = static_cast<char*>(buffer.raw) + Offset;
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Type size is too large");
|
||||
|
||||
::new (p) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref_at_offset<T, Offset>();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -209,9 +215,9 @@ namespace etl
|
||||
template <typename T>
|
||||
ETL_NODISCARD T& ref()
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large");
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of type too large for storage");
|
||||
|
||||
return *static_cast<T*>(buffer);
|
||||
return *reinterpret_cast<T*>(buffer.raw);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -220,9 +226,9 @@ namespace etl
|
||||
template <typename T>
|
||||
ETL_NODISCARD const T& ref() const
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of T is too large");
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= Size, "Size of type too large for storage");
|
||||
|
||||
return *static_cast<const T*>(buffer);
|
||||
return *reinterpret_cast<const T*>(buffer.raw);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -233,9 +239,7 @@ namespace etl
|
||||
{
|
||||
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
char* p = buffer + offset;
|
||||
|
||||
return *static_cast<T*>(p);
|
||||
return *reinterpret_cast<T*>(buffer.raw + offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -246,9 +250,7 @@ namespace etl
|
||||
{
|
||||
ETL_ASSERT(sizeof(T) <= (Size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
char* p = buffer + offset;
|
||||
|
||||
return *static_cast<const T*>(p);
|
||||
return *reinterpret_cast<const T*>(buffer.raw + offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -257,11 +259,9 @@ namespace etl
|
||||
template <typename T, size_t Offset>
|
||||
ETL_NODISCARD T& ref_at_offset()
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of T is too large");
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of type too large for storage");
|
||||
|
||||
char* p = buffer + Offset;
|
||||
|
||||
return *static_cast<T*>(p);
|
||||
return *reinterpret_cast<T*>(buffer.raw + Offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -270,11 +270,9 @@ namespace etl
|
||||
template <typename T, size_t Offset>
|
||||
ETL_NODISCARD const T& ref_at_offset() const
|
||||
{
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of T is too large");
|
||||
ETL_STATIC_ASSERT(sizeof(T) <= (Size - Offset), "Size of type too large for storage");
|
||||
|
||||
char* p = buffer + Offset;
|
||||
|
||||
return *static_cast<const T*>(p);
|
||||
return *reinterpret_cast<const T*>(buffer.raw + Offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -411,38 +409,44 @@ namespace etl
|
||||
/// Emplace from parameters
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace(TArgs... args)
|
||||
T& emplace(TArgs... args)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
::new (pbuffer) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref<T>();
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Emplace from parameters at offset
|
||||
//***********************************
|
||||
template <typename T, typename... TArgs>
|
||||
void emplace_at_offset(size_t offset, TArgs... args)
|
||||
T& emplace_at_offset(size_t offset, TArgs... args)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
::new (p) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref_at_offset<T>(offset);
|
||||
}
|
||||
|
||||
//***********************************
|
||||
/// Emplace from parameters at offset
|
||||
//***********************************
|
||||
template <typename T, size_t Offset, typename... TArgs>
|
||||
void emplace_at_offset(TArgs... args)
|
||||
T& emplace_at_offset(TArgs... args)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + Offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
::new (p) T(etl::forward<TArgs>(args)...);
|
||||
|
||||
return ref_at_offset<T, Offset>();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -455,7 +459,9 @@ namespace etl
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<T*>(pbuffer);
|
||||
T* p = reinterpret_cast<T*>(pbuffer);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -467,7 +473,9 @@ namespace etl
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
ETL_ASSERT(sizeof(T) <= buffer_size, ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<const T*>(pbuffer);
|
||||
const T* p = reinterpret_cast<const T*>(pbuffer);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -477,10 +485,11 @@ namespace etl
|
||||
ETL_NODISCARD T& ref_at_offset(size_t offset)
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<T*>(p);
|
||||
T* p = reinterpret_cast<T*>(pbuffer + offset);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -490,10 +499,11 @@ namespace etl
|
||||
ETL_NODISCARD const T& ref_at_offset(size_t offset) const
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<const T*>(p);
|
||||
const T* p = reinterpret_cast<const T*>(pbuffer + offset);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -503,10 +513,11 @@ namespace etl
|
||||
ETL_NODISCARD T& ref_at_offset()
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + Offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<T*>(p);
|
||||
T* p = reinterpret_cast<T*>(pbuffer + Offset);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
@ -516,10 +527,11 @@ namespace etl
|
||||
ETL_NODISCARD const T& ref_at_offset() const
|
||||
{
|
||||
ETL_ASSERT((pbuffer != ETL_NULLPTR), ETL_ERROR(etl::mem_cast_nullptr_exception));
|
||||
char* p = pbuffer + Offset;
|
||||
ETL_ASSERT(sizeof(T) <= (buffer_size - Offset), ETL_ERROR(etl::mem_cast_size_exception));
|
||||
|
||||
return *reinterpret_cast<const T*>(p);
|
||||
const T* p = reinterpret_cast<const T*>(pbuffer + Offset);
|
||||
|
||||
return *p;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
|
||||
@ -54,6 +54,27 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*****************************************************************************
|
||||
/// Obtain the address represented by p without forming a reference to the object pointed to by p.
|
||||
/// Defined when not using the STL or C++20
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR T* to_address(T* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
/// Obtain the address represented by itr without forming a reference to the object pointed to by itr.
|
||||
/// Requires that the iterator defines operator->()
|
||||
/// Defined when not using the STL or C++20
|
||||
//*****************************************************************************
|
||||
template <typename Iterator>
|
||||
ETL_CONSTEXPR typename Iterator::pointer to_address(const Iterator& itr)
|
||||
{
|
||||
return etl::to_address(itr.operator->());
|
||||
}
|
||||
|
||||
#if ETL_USING_STL
|
||||
//*****************************************************************************
|
||||
/// Fills uninitialised memory range with a value.
|
||||
@ -112,7 +133,7 @@ namespace etl
|
||||
|
||||
while (o_begin != o_end)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type(value);
|
||||
::new (static_cast<void*>(etl::to_address(o_begin))) value_type(value);
|
||||
++o_begin;
|
||||
}
|
||||
|
||||
@ -259,7 +280,7 @@ namespace etl
|
||||
|
||||
while (i_begin != i_end)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(*i_begin);
|
||||
::new (static_cast<void*>(etl::to_address(o_end))) value_type(*i_begin);
|
||||
++i_begin;
|
||||
++o_end;
|
||||
}
|
||||
@ -407,7 +428,7 @@ namespace etl
|
||||
|
||||
while (i_begin != i_end)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
|
||||
::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
|
||||
++i_begin;
|
||||
++o_end;
|
||||
}
|
||||
@ -532,7 +553,7 @@ namespace etl
|
||||
|
||||
while (n-- != 0)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_end))) value_type(etl::move(*i_begin));
|
||||
::new (static_cast<void*>(etl::to_address(o_end))) value_type(etl::move(*i_begin));
|
||||
++i_begin;
|
||||
++o_end;
|
||||
}
|
||||
@ -665,7 +686,7 @@ namespace etl
|
||||
|
||||
while (o_begin != o_end)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type;
|
||||
::new (static_cast<void*>(etl::to_address(o_begin))) value_type;
|
||||
++o_begin;
|
||||
}
|
||||
}
|
||||
@ -844,7 +865,7 @@ namespace etl
|
||||
|
||||
while (o_begin != o_end)
|
||||
{
|
||||
::new (static_cast<void*>(etl::addressof(*o_begin))) value_type();
|
||||
::new (static_cast<void*>(etl::to_address(o_begin))) value_type();
|
||||
++o_begin;
|
||||
}
|
||||
}
|
||||
@ -1095,7 +1116,7 @@ namespace etl
|
||||
{
|
||||
while (i_begin != i_end)
|
||||
{
|
||||
etl::destroy_at(etl::addressof(*i_begin));
|
||||
etl::destroy_at(etl::to_address(i_begin));
|
||||
++i_begin;
|
||||
}
|
||||
}
|
||||
@ -1127,7 +1148,7 @@ namespace etl
|
||||
|
||||
while (i_begin != i_end)
|
||||
{
|
||||
etl::destroy_at(etl::addressof(*i_begin));
|
||||
etl::destroy_at(etl::to_address(i_begin));
|
||||
++i_begin;
|
||||
}
|
||||
}
|
||||
@ -1182,7 +1203,7 @@ namespace etl
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
etl::destroy_at(etl::addressof(*i_begin));
|
||||
etl::destroy_at(etl::to_address(i_begin));
|
||||
++i_begin;
|
||||
--n;
|
||||
}
|
||||
@ -1218,7 +1239,7 @@ namespace etl
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
etl::destroy_at(etl::addressof(*i_begin));
|
||||
etl::destroy_at(etl::to_address(i_begin));
|
||||
++i_begin;
|
||||
--n;
|
||||
}
|
||||
@ -2264,13 +2285,13 @@ namespace etl
|
||||
/// \param destination begin
|
||||
/// \return A pointer to the destination.
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, TPointer>::type
|
||||
mem_copy(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, T*>::type
|
||||
mem_copy(const T* sb, const T* se, T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
|
||||
return reinterpret_cast<T*>(memcpy(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb)));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2280,13 +2301,13 @@ namespace etl
|
||||
/// \param source length
|
||||
/// \param destination begin
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, TPointer>::type
|
||||
mem_copy(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, T*>::type
|
||||
mem_copy(const T* sb, size_t n, T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast<TPointer>(memcpy(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
|
||||
return reinterpret_cast<T*>(memcpy(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * n));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2296,13 +2317,13 @@ namespace etl
|
||||
/// \param source end
|
||||
/// \param destination begin
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, TPointer>::type
|
||||
mem_move(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, T*>::type
|
||||
mem_move(const T* sb, const T* se, T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb)));
|
||||
return reinterpret_cast<T*>(memmove(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb)));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2312,32 +2333,32 @@ namespace etl
|
||||
/// \param source length
|
||||
/// \param destination begin
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, TPointer>::type
|
||||
mem_move(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, T*>::type
|
||||
mem_move(const T* sb, size_t n, T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast<TPointer>(memmove(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * n));
|
||||
return reinterpret_cast<T*>(memmove(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * n));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Template wrapper for memcmp.
|
||||
/// \param source begin
|
||||
/// \param source end
|
||||
/// \param destination begin
|
||||
/// \param sb Source begin
|
||||
/// \param se Source end
|
||||
/// \param db Destination begin
|
||||
/// \return < 0 The first byte that does not match in both memory blocks has a lower value in 'sb' than in 'db' when evaluated as unsigned char values.
|
||||
/// 0 The contents of both memory blocks are equal
|
||||
/// > 0 The first byte that does not match in both memory blocks has a greater value in 'sb' than in 'db' when evaluated as unsigned char values.
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
template <typename T>
|
||||
ETL_NODISCARD
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, int>::type
|
||||
mem_compare(const TPointer sb, const TPointer se, TPointer db) ETL_NOEXCEPT
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, int>::type
|
||||
mem_compare(const T* sb, const T* se, const T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return memcmp(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * static_cast<size_t>(se - sb));
|
||||
return memcmp(reinterpret_cast<const void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * static_cast<size_t>(se - sb));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2349,14 +2370,14 @@ namespace etl
|
||||
/// 0 The contents of both memory blocks are equal
|
||||
/// > 0 The first byte that does not match in both memory blocks has a greater value in 'sb' than in 'db' when evaluated as unsigned char values.
|
||||
//***************************************************************************
|
||||
template <typename TPointer>
|
||||
template <typename T>
|
||||
ETL_NODISCARD
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, int>::type
|
||||
mem_compare(const TPointer sb, size_t n, TPointer db) ETL_NOEXCEPT
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<T*>::value_type>::value, int>::type
|
||||
mem_compare(const T* sb, size_t n, const T* db) ETL_NOEXCEPT
|
||||
{
|
||||
return memcmp(reinterpret_cast<void*>(db),
|
||||
reinterpret_cast<void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<TPointer>::value_type) * n);
|
||||
return memcmp(reinterpret_cast<const void*>(db),
|
||||
reinterpret_cast<const void*>(sb),
|
||||
sizeof(typename etl::iterator_traits<T*>::value_type) * n);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -2384,7 +2405,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename TPointer, typename T>
|
||||
typename etl::enable_if<etl::is_trivially_copyable<typename etl::iterator_traits<TPointer>::value_type>::value, TPointer>::type
|
||||
mem_set(const TPointer db, size_t n, T value) ETL_NOEXCEPT
|
||||
mem_set(TPointer db, size_t n, T value) ETL_NOEXCEPT
|
||||
{
|
||||
return reinterpret_cast<TPointer>(memset(reinterpret_cast<void*>(db),
|
||||
static_cast<char>(value),
|
||||
|
||||
@ -53,8 +53,6 @@ SOFTWARE.
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
|
||||
#include "message.h"
|
||||
#include "error_handler.h"
|
||||
#include "static_assert.h"
|
||||
@ -286,11 +284,39 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
#if !ETL_HAS_VIRTUAL_MESSAGES
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
(delete_message_type<TMessageTypes>(pmsg) || ...);
|
||||
}
|
||||
|
||||
//********************************************
|
||||
template <typename TType>
|
||||
bool delete_message_type(etl::imessage* pmsg)
|
||||
{
|
||||
if (TType::ID == pmsg->get_message_id())
|
||||
{
|
||||
TType* p = static_cast<TType*>(pmsg);
|
||||
p->~TType();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -584,11 +610,40 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
case T12::ID: static_cast<const T12*>(pmsg)->~T12(); break;
|
||||
case T13::ID: static_cast<const T13*>(pmsg)->~T13(); break;
|
||||
case T14::ID: static_cast<const T14*>(pmsg)->~T14(); break;
|
||||
case T15::ID: static_cast<const T15*>(pmsg)->~T15(); break;
|
||||
case T16::ID: static_cast<const T16*>(pmsg)->~T16(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -613,7 +668,7 @@ namespace etl
|
||||
case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break;
|
||||
case T15::ID: ::new (p) T15(static_cast<const T15&>(msg)); break;
|
||||
case T16::ID: ::new (p) T16(static_cast<const T16&>(msg)); break;
|
||||
default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -642,7 +697,7 @@ namespace etl
|
||||
case T14::ID: ::new (p) T14(static_cast<T14&&>(msg)); break;
|
||||
case T15::ID: ::new (p) T15(static_cast<T15&&>(msg)); break;
|
||||
case T16::ID: ::new (p) T16(static_cast<T16&&>(msg)); break;
|
||||
default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -879,11 +934,40 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
case T12::ID: static_cast<const T12*>(pmsg)->~T12(); break;
|
||||
case T13::ID: static_cast<const T13*>(pmsg)->~T13(); break;
|
||||
case T14::ID: static_cast<const T14*>(pmsg)->~T14(); break;
|
||||
case T15::ID: static_cast<const T15*>(pmsg)->~T15(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -907,7 +991,7 @@ namespace etl
|
||||
case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break;
|
||||
case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break;
|
||||
case T15::ID: ::new (p) T15(static_cast<const T15&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1172,11 +1256,39 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
case T12::ID: static_cast<const T12*>(pmsg)->~T12(); break;
|
||||
case T13::ID: static_cast<const T13*>(pmsg)->~T13(); break;
|
||||
case T14::ID: static_cast<const T14*>(pmsg)->~T14(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -1199,7 +1311,7 @@ namespace etl
|
||||
case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break;
|
||||
case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break;
|
||||
case T14::ID: ::new (p) T14(static_cast<const T14&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1463,11 +1575,38 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
case T12::ID: static_cast<const T12*>(pmsg)->~T12(); break;
|
||||
case T13::ID: static_cast<const T13*>(pmsg)->~T13(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -1489,7 +1628,7 @@ namespace etl
|
||||
case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break;
|
||||
case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break;
|
||||
case T13::ID: ::new (p) T13(static_cast<const T13&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1748,11 +1887,37 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
case T12::ID: static_cast<const T12*>(pmsg)->~T12(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -1773,7 +1938,7 @@ namespace etl
|
||||
case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break;
|
||||
case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break;
|
||||
case T12::ID: ::new (p) T12(static_cast<const T12&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2031,11 +2196,36 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
case T11::ID: static_cast<const T11*>(pmsg)->~T11(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -2055,7 +2245,7 @@ namespace etl
|
||||
case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break;
|
||||
case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break;
|
||||
case T11::ID: ::new (p) T11(static_cast<const T11&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2312,11 +2502,35 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
case T10::ID: static_cast<const T10*>(pmsg)->~T10(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -2335,7 +2549,7 @@ namespace etl
|
||||
case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break;
|
||||
case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break;
|
||||
case T10::ID: ::new (p) T10(static_cast<const T10&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2591,11 +2805,34 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
case T9::ID: static_cast<const T9*>(pmsg)->~T9(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -2613,7 +2850,7 @@ namespace etl
|
||||
case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break;
|
||||
case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break;
|
||||
case T9::ID: ::new (p) T9(static_cast<const T9&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2864,11 +3101,33 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
case T8::ID: static_cast<const T8*>(pmsg)->~T8(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -2885,7 +3144,7 @@ namespace etl
|
||||
case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break;
|
||||
case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break;
|
||||
case T8::ID: ::new (p) T8(static_cast<const T8&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3135,11 +3394,32 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
case T7::ID: static_cast<const T7*>(pmsg)->~T7(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -3155,7 +3435,7 @@ namespace etl
|
||||
case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break;
|
||||
case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break;
|
||||
case T7::ID: ::new (p) T7(static_cast<const T7&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3404,11 +3684,31 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
case T6::ID: static_cast<const T6*>(pmsg)->~T6(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -3423,7 +3723,7 @@ namespace etl
|
||||
case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break;
|
||||
case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break;
|
||||
case T6::ID: ::new (p) T6(static_cast<const T6&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3671,11 +3971,30 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
case T5::ID: static_cast<const T5*>(pmsg)->~T5(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -3689,7 +4008,7 @@ namespace etl
|
||||
case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break;
|
||||
case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break;
|
||||
case T5::ID: ::new (p) T5(static_cast<const T5&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3932,11 +4251,29 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
case T4::ID: static_cast<const T4*>(pmsg)->~T4(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -3949,7 +4286,7 @@ namespace etl
|
||||
case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break;
|
||||
case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break;
|
||||
case T4::ID: ::new (p) T4(static_cast<const T4&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4191,11 +4528,28 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
case T3::ID: static_cast<const T3*>(pmsg)->~T3(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -4207,7 +4561,7 @@ namespace etl
|
||||
case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break;
|
||||
case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break;
|
||||
case T3::ID: ::new (p) T3(static_cast<const T3&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4448,11 +4802,27 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
case T2::ID: static_cast<const T2*>(pmsg)->~T2(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -4463,7 +4833,7 @@ namespace etl
|
||||
{
|
||||
case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break;
|
||||
case T2::ID: ::new (p) T2(static_cast<const T2&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4703,11 +5073,26 @@ namespace etl
|
||||
{
|
||||
etl::imessage* pmsg = static_cast<etl::imessage*>(data);
|
||||
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
pmsg->~imessage();
|
||||
#else
|
||||
delete_message(pmsg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//********************************************
|
||||
void delete_message(etl::imessage* pmsg)
|
||||
{
|
||||
switch (pmsg->get_message_id())
|
||||
{
|
||||
case T1::ID: static_cast<const T1*>(pmsg)->~T1(); break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************
|
||||
void add_new_message(const etl::imessage& msg)
|
||||
{
|
||||
@ -4717,7 +5102,7 @@ namespace etl
|
||||
switch (id)
|
||||
{
|
||||
case T1::ID: ::new (p) T1(static_cast<const T1&>(msg)); break;
|
||||
default: break;
|
||||
default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4741,8 +5126,5 @@ namespace etl
|
||||
};
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#error "etl::message_packet is not compatible with non-virtual etl::imessage"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -54,9 +54,7 @@ SOFTWARE.
|
||||
#include "platform.h"
|
||||
#include "message.h"
|
||||
#include "shared_message.h"
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
#include "message_packet.h"
|
||||
#endif
|
||||
#include "message_packet.h"
|
||||
#include "message_types.h"
|
||||
#include "alignment.h"
|
||||
#include "error_handler.h"
|
||||
@ -412,9 +410,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<TMessageTypes...> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router()
|
||||
@ -562,9 +558,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -709,9 +703,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -856,9 +848,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1002,9 +992,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1146,9 +1134,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1289,9 +1275,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1431,9 +1415,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1572,9 +1554,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8, T9> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1711,9 +1691,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7, T8> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1849,9 +1827,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6, T7> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -1985,9 +1961,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5, T6> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -2120,9 +2094,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4, T5> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -2253,9 +2225,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3, T4> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -2385,9 +2355,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2, T3> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -2516,9 +2484,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet<T1, T2> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
@ -2646,9 +2612,7 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_HAS_VIRTUAL_MESSAGES
|
||||
typedef etl::message_packet< T1> message_packet;
|
||||
#endif
|
||||
|
||||
//**********************************************
|
||||
message_router(etl::message_router_id_t id_)
|
||||
|
||||
46
include/etl/monostate.h
Normal file
46
include/etl/monostate.h
Normal file
@ -0,0 +1,46 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 jwellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_MONOSTATE_INCLUDED
|
||||
#define ETL_MONOSTATE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// A 'no-value' placeholder.
|
||||
//***************************************************************************
|
||||
struct monostate
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -38,7 +38,7 @@ SOFTWARE.
|
||||
#include "span.h"
|
||||
|
||||
///\defgroup multi_multi_span multi_span multi_span
|
||||
/// Scatter/Gather functionality
|
||||
/// Allows Scatter/Gather functionality
|
||||
///\ingroup containers
|
||||
|
||||
namespace etl
|
||||
@ -62,36 +62,56 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Iterator
|
||||
//*************************************************************************
|
||||
class iterator : public etl::iterator<ETL_OR_STD::forward_iterator_tag, element_type>
|
||||
class iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, element_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class multi_span;
|
||||
friend class const_iterator;
|
||||
|
||||
iterator()
|
||||
: p_current(ETL_NULLPTR)
|
||||
, p_end(ETL_NULLPTR)
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 iterator()
|
||||
: p_span_list(ETL_NULLPTR)
|
||||
, p_current_span(ETL_NULLPTR)
|
||||
, p_value(ETL_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
iterator& operator ++()
|
||||
ETL_CONSTEXPR14 iterator(const iterator& other)
|
||||
: p_span_list(other.p_span_list)
|
||||
, p_current_span(other.p_current_span)
|
||||
, p_value(other.p_value)
|
||||
{
|
||||
if (p_current != p_end)
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 iterator& operator =(const iterator& rhs)
|
||||
{
|
||||
p_span_list = rhs.p_span_list;
|
||||
p_current_span = rhs.p_current_span;
|
||||
p_value = rhs.p_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 iterator& operator ++()
|
||||
{
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
++p_value;
|
||||
|
||||
if (p_value == p_current->end())
|
||||
if (p_value == p_current_span->end())
|
||||
{
|
||||
do
|
||||
{
|
||||
++p_current;
|
||||
} while ((p_current != p_end) && p_current->empty());
|
||||
++p_current_span;
|
||||
} while ((p_current_span != p_span_list->end()) && p_current_span->empty());
|
||||
|
||||
if (p_current != p_end)
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
p_value = p_current->begin();
|
||||
p_value = p_current_span->begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -104,7 +124,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
iterator operator ++(int)
|
||||
ETL_CONSTEXPR14 iterator operator ++(int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
|
||||
@ -113,10 +133,54 @@ namespace etl
|
||||
return temp;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 iterator& operator --()
|
||||
{
|
||||
if (p_current_span == p_span_list->end())
|
||||
{
|
||||
--p_current_span;
|
||||
p_value = p_current_span->end();
|
||||
--p_value;
|
||||
}
|
||||
else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
|
||||
{
|
||||
if (p_value == p_current_span->begin())
|
||||
{
|
||||
do
|
||||
{
|
||||
--p_current_span;
|
||||
} while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
|
||||
|
||||
p_value = p_current_span->end();
|
||||
--p_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
--p_value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_value = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 iterator operator --(int)
|
||||
{
|
||||
iterator temp = *this;
|
||||
|
||||
operator --();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// * operator
|
||||
//*************************************************************************
|
||||
reference operator *()
|
||||
ETL_CONSTEXPR14 reference operator *()
|
||||
{
|
||||
return *p_value;
|
||||
}
|
||||
@ -124,7 +188,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// * operator
|
||||
//*************************************************************************
|
||||
const_reference operator *() const
|
||||
ETL_CONSTEXPR14 const_reference operator *() const
|
||||
{
|
||||
return *p_value;
|
||||
}
|
||||
@ -132,55 +196,57 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// -> operator
|
||||
//*************************************************************************
|
||||
pointer operator ->()
|
||||
ETL_CONSTEXPR14 pointer operator ->()
|
||||
{
|
||||
return &operator*();
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// -> operator
|
||||
//*************************************************************************
|
||||
const_pointer operator ->() const
|
||||
ETL_CONSTEXPR14 const_pointer operator ->() const
|
||||
{
|
||||
return &operator*();
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// == operator
|
||||
//*************************************************************************
|
||||
friend bool operator ==(const iterator& lhs, const iterator& rhs)
|
||||
ETL_CONSTEXPR14 friend bool operator ==(const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return (lhs.p_current == rhs.p_current);
|
||||
return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// != operator
|
||||
//*************************************************************************
|
||||
friend bool operator !=(const iterator& lhs, const iterator& rhs)
|
||||
ETL_CONSTEXPR14 friend bool operator !=(const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef const span_type* span_pointer;
|
||||
typedef const span_list_type* span_list_pointer;
|
||||
typedef typename span_list_type::iterator span_list_iterator;
|
||||
|
||||
//*****************************************
|
||||
iterator(span_list_iterator p_current_, span_list_iterator p_end_)
|
||||
: p_current(p_current_)
|
||||
, p_end(p_end_)
|
||||
ETL_CONSTEXPR14 iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
|
||||
: p_span_list(&span_list_)
|
||||
, p_current_span(p_current_span_)
|
||||
, p_value(ETL_NULLPTR)
|
||||
{
|
||||
if (p_current != p_end)
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
while ((p_current != p_end) && p_current->empty())
|
||||
while ((p_current_span != p_span_list->end()) && p_current_span->empty())
|
||||
{
|
||||
++p_current;
|
||||
++p_current_span;
|
||||
}
|
||||
|
||||
if (p_current != p_end)
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
p_value = p_current->begin();
|
||||
p_value = p_current_span->begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -189,13 +255,216 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
typedef const span_type* span_list_pointer;
|
||||
|
||||
span_list_pointer p_current;
|
||||
span_list_pointer p_end;
|
||||
span_list_pointer p_span_list;
|
||||
span_pointer p_current_span;
|
||||
pointer p_value;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Const Iterator
|
||||
//*************************************************************************
|
||||
class const_iterator : public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const element_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class multi_span;
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator()
|
||||
: p_span_list(ETL_NULLPTR)
|
||||
, p_current_span(ETL_NULLPTR)
|
||||
, p_value(ETL_NULLPTR)
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator(const const_iterator& other)
|
||||
: p_span_list(other.p_span_list)
|
||||
, p_current_span(other.p_current_span)
|
||||
, p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator& operator =(const const_iterator& rhs)
|
||||
{
|
||||
p_span_list = rhs.p_span_list;
|
||||
p_current_span = rhs.p_current_span;
|
||||
p_value = rhs.p_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator(const etl::multi_span<T>::iterator& other)
|
||||
: p_span_list(other.p_span_list)
|
||||
, p_current_span(other.p_current_span)
|
||||
, p_value(other.p_value)
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator& operator =(const etl::multi_span<T>::iterator& rhs)
|
||||
{
|
||||
p_span_list = rhs.p_span_list;
|
||||
p_current_span = rhs.p_current_span;
|
||||
p_value = rhs.p_value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator& operator ++()
|
||||
{
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
++p_value;
|
||||
|
||||
if (p_value == p_current_span->end())
|
||||
{
|
||||
do
|
||||
{
|
||||
++p_current_span;
|
||||
} while ((p_current_span != p_span_list->end()) && p_current_span->empty());
|
||||
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
p_value = p_current_span->begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
p_value = ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator operator ++(int)
|
||||
{
|
||||
const_iterator temp = *this;
|
||||
|
||||
operator ++();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator& operator --()
|
||||
{
|
||||
if (p_current_span == p_span_list->end())
|
||||
{
|
||||
--p_current_span;
|
||||
p_value = p_current_span->end();
|
||||
--p_value;
|
||||
}
|
||||
else if ((p_current_span != p_span_list->begin()) || (p_value != p_current_span->begin()))
|
||||
{
|
||||
if (p_value == p_current_span->begin())
|
||||
{
|
||||
do
|
||||
{
|
||||
--p_current_span;
|
||||
} while ((p_current_span != p_span_list->begin()) && p_current_span->empty());
|
||||
|
||||
p_value = p_current_span->end();
|
||||
--p_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
--p_value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_value = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator operator --(int)
|
||||
{
|
||||
const_iterator temp = *this;
|
||||
|
||||
operator --();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// * operator
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 const_reference operator *() const
|
||||
{
|
||||
return *p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// -> operator
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 const_pointer operator ->() const
|
||||
{
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// == operator
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 friend bool operator ==(const const_iterator& lhs, const const_iterator& rhs)
|
||||
{
|
||||
return (lhs.p_current_span == rhs.p_current_span) && (lhs.p_value == rhs.p_value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// != operator
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 friend bool operator !=(const const_iterator& lhs, const const_iterator& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef const span_type* span_pointer;
|
||||
typedef const span_list_type* span_list_pointer;
|
||||
typedef const typename span_list_type::iterator span_list_iterator;
|
||||
|
||||
//*****************************************
|
||||
ETL_CONSTEXPR14 const_iterator(const span_list_type& span_list_, span_list_iterator p_current_span_)
|
||||
: p_span_list(&span_list_)
|
||||
, p_current_span(p_current_span_)
|
||||
, p_value(ETL_NULLPTR)
|
||||
{
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
while ((p_current_span != p_span_list->end()) && p_current_span->empty())
|
||||
{
|
||||
++p_current_span;
|
||||
}
|
||||
|
||||
if (p_current_span != p_span_list->end())
|
||||
{
|
||||
p_value = p_current_span->begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
p_value = ETL_NULLPTR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span_list_pointer p_span_list;
|
||||
span_pointer p_current_span;
|
||||
const_pointer p_value;
|
||||
};
|
||||
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
@ -229,7 +498,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR14 multi_span(TIterator begin_, TIterator end_)
|
||||
: span_list(etl::addressof(*begin_), etl::distance(begin_, end_))
|
||||
: span_list(etl::to_address(begin_), etl::distance(begin_, end_))
|
||||
{
|
||||
}
|
||||
|
||||
@ -238,7 +507,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR14 multi_span(TIterator begin_, size_t length_)
|
||||
: span_list(etl::addressof(*begin_), length_)
|
||||
: span_list(etl::to_address(begin_), length_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -253,7 +522,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Assignment operator
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 multi_span& operator = (const multi_span & other)
|
||||
ETL_CONSTEXPR14 multi_span& operator =(const multi_span & other)
|
||||
{
|
||||
span_list = other.span_list;
|
||||
|
||||
@ -265,7 +534,15 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 iterator begin() const
|
||||
{
|
||||
return iterator(span_list.begin(), span_list.end());
|
||||
return iterator(span_list, span_list.begin());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(span_list, span_list.cbegin());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -273,7 +550,66 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 iterator end() const
|
||||
{
|
||||
return iterator(span_list.end(), span_list.end());
|
||||
return iterator(span_list, span_list.end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 const_iterator cend() const
|
||||
{
|
||||
return const_iterator(span_list, span_list.cend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 reverse_iterator rbegin() const
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 reverse_iterator crbegin() const
|
||||
{
|
||||
return const_reverse_iterator(cend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 reverse_iterator rend() const
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
///
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 const_reverse_iterator crend() const
|
||||
{
|
||||
return const_reverse_iterator(cbegin());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reference to the indexed value.
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 reference operator[](size_t i) const
|
||||
{
|
||||
// Find the span in the span list.
|
||||
size_t number_of_spans = span_list.size();
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
while ((i >= span_list[index].size()) && (index < number_of_spans))
|
||||
{
|
||||
i -= span_list[index].size();
|
||||
++index;
|
||||
}
|
||||
|
||||
return span_list[index][i];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
@ -30,25 +30,43 @@ SOFTWARE.
|
||||
#define ETL_NTH_TYPE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "static_assert.h"
|
||||
|
||||
#if ETL_NOT_USING_CPP11
|
||||
#if !defined(ETL_IN_UNIT_TEST)
|
||||
#error NOT SUPPORTED FOR C++03 OR BELOW
|
||||
#endif
|
||||
#else
|
||||
namespace etl
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
template <size_t N, typename T1, typename... TRest>
|
||||
namespace private_nth_type
|
||||
{
|
||||
//***********************************
|
||||
template <size_t N, typename T1, typename... TRest>
|
||||
struct nth_type_helper
|
||||
{
|
||||
using type = typename nth_type_helper<N - 1U, TRest...>::type;
|
||||
};
|
||||
|
||||
template <typename T1, typename... TRest>
|
||||
struct nth_type_helper<0U, T1, TRest...>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
}
|
||||
|
||||
//***********************************
|
||||
template <size_t N, typename... TTypes>
|
||||
struct nth_type
|
||||
{
|
||||
using type = typename nth_type<N - 1U, TRest...>::type;
|
||||
};
|
||||
|
||||
template <typename T1, typename... TRest>
|
||||
struct nth_type<0U, T1, TRest...>
|
||||
{
|
||||
using type = T1;
|
||||
ETL_STATIC_ASSERT(N < sizeof...(TTypes), "etl::nth_type index 'N' out of bounds");
|
||||
|
||||
using type = typename private_nth_type::nth_type_helper<N, TTypes...>::type;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
template <size_t N, typename... TTypes>
|
||||
using nth_type_t = typename nth_type<N, TTypes...>::type;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -484,14 +484,16 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename... TArgs>
|
||||
ETL_CONSTEXPR20_STL
|
||||
void emplace(TArgs&& ... args)
|
||||
T& emplace(TArgs&& ... args)
|
||||
{
|
||||
storage.construct(etl::forward<TArgs>(args)...);
|
||||
|
||||
return storage.u.value;
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplaces a value.
|
||||
/// 1 parameter.
|
||||
/// 0 parameters.
|
||||
//*************************************************************************
|
||||
T& emplace()
|
||||
{
|
||||
@ -1048,14 +1050,16 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename... TArgs>
|
||||
ETL_CONSTEXPR14
|
||||
void emplace(TArgs&& ... args)
|
||||
T& emplace(TArgs&& ... args)
|
||||
{
|
||||
storage.construct(etl::forward<TArgs>(args)...);
|
||||
|
||||
return storage.value;
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Emplaces a value.
|
||||
/// 1 parameter.
|
||||
/// 0 parameters.
|
||||
//*************************************************************************
|
||||
T& emplace()
|
||||
{
|
||||
|
||||
@ -134,7 +134,7 @@ namespace etl
|
||||
inline constexpr size_t parameter_pack_v = etl::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17 && (!ETL_USING_GCC_COMPILER || (__GNUC__ > 7))
|
||||
#if ETL_USING_CPP17 && !ETL_USING_GCC_COMPILER
|
||||
//***********************************
|
||||
template <typename... TTypes>
|
||||
template <typename T>
|
||||
|
||||
@ -314,7 +314,7 @@ SOFTWARE.
|
||||
//*************************************
|
||||
// The macros below are dependent on the profile.
|
||||
// C++11
|
||||
#if ETL_USING_CPP11 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
|
||||
#if ETL_USING_CPP11
|
||||
#define ETL_CONSTEXPR constexpr
|
||||
#define ETL_CONSTEXPR11 constexpr // Synonym for ETL_CONSTEXPR
|
||||
#define ETL_CONSTANT constexpr
|
||||
@ -354,10 +354,16 @@ SOFTWARE.
|
||||
|
||||
//*************************************
|
||||
// C++14
|
||||
#if ETL_USING_CPP14 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
|
||||
#define ETL_CONSTEXPR14 constexpr
|
||||
#define ETL_DEPRECATED [[deprecated]]
|
||||
#define ETL_DEPRECATED_REASON(reason) [[deprecated(reason)]]
|
||||
#if ETL_USING_CPP14
|
||||
#define ETL_CONSTEXPR14 constexpr
|
||||
|
||||
#if !defined(ETL_IN_UNIT_TEST)
|
||||
#define ETL_DEPRECATED [[deprecated]]
|
||||
#define ETL_DEPRECATED_REASON(reason) [[deprecated(reason)]]
|
||||
#else
|
||||
#define ETL_DEPRECATED
|
||||
#define ETL_DEPRECATED_REASON(reason)
|
||||
#endif
|
||||
#else
|
||||
#define ETL_CONSTEXPR14
|
||||
#define ETL_DEPRECATED
|
||||
@ -366,7 +372,7 @@ SOFTWARE.
|
||||
|
||||
//*************************************
|
||||
// C++17
|
||||
#if ETL_USING_CPP17 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
|
||||
#if ETL_USING_CPP17
|
||||
#define ETL_CONSTEXPR17 constexpr
|
||||
#define ETL_IF_CONSTEXPR constexpr
|
||||
#define ETL_NODISCARD [[nodiscard]]
|
||||
@ -384,7 +390,7 @@ SOFTWARE.
|
||||
|
||||
//*************************************
|
||||
// C++20
|
||||
#if ETL_USING_CPP20 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
|
||||
#if ETL_USING_CPP20
|
||||
#define ETL_LIKELY [[likely]]
|
||||
#define ETL_UNLIKELY [[unlikely]]
|
||||
#define ETL_CONSTEXPR20 constexpr
|
||||
@ -410,7 +416,7 @@ SOFTWARE.
|
||||
|
||||
//*************************************
|
||||
// C++23
|
||||
#if ETL_USING_CPP23 && !defined(ETL_FORCE_NO_ADVANCED_CPP)
|
||||
#if ETL_USING_CPP23
|
||||
#define ETL_ASSUME(expression) [[assume(expression)]]
|
||||
#else
|
||||
#define ETL_ASSUME ETL_DO_NOTHING
|
||||
@ -468,6 +474,15 @@ SOFTWARE.
|
||||
#else
|
||||
#define ETL_HAS_ATOMIC 0
|
||||
#endif
|
||||
#if ((ETL_USING_CPP17 && (ETL_USING_STL || defined(ETL_IN_UNIT_TEST))) || \
|
||||
defined(ETL_COMPILER_ARM5) || \
|
||||
defined(ETL_COMPILER_ARM6) || \
|
||||
defined(ETL_COMPILER_GCC) || \
|
||||
defined(ETL_COMPILER_CLANG))
|
||||
#define ETL_HAS_ATOMIC_ALWAYS_LOCK_FREE 1
|
||||
#else
|
||||
#define ETL_HAS_ATOMIC_ALWAYS_LOCK_FREE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//*************************************
|
||||
@ -494,6 +509,26 @@ SOFTWARE.
|
||||
#define ETL_HAS_INITIALIZER_LIST 0
|
||||
#endif
|
||||
|
||||
//*************************************
|
||||
// Determine if the ETL should use __attribute__((packed).
|
||||
#if defined(ETL_COMPILER_CLANG) || defined(ETL_COMPILER_GCC) || defined(ETL_COMPILER_INTEL) || defined(ETL_COMPILER_ARM6)
|
||||
#define ETL_PACKED_CLASS(class_type) class __attribute__((packed)) class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) struct __attribute__((packed)) struct_type
|
||||
#define ETL_END_PACKED
|
||||
#define ETL_HAS_PACKED 1
|
||||
#elif defined(ETL_COMPILER_MICROSOFT)
|
||||
#define ETL_PACKED_CLASS(class_type) __pragma(pack(push, 1)) class class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) __pragma(pack(push, 1)) struct struct_type
|
||||
#define ETL_PACKED
|
||||
#define ETL_END_PACKED __pragma(pack(pop))
|
||||
#define ETL_HAS_PACKED 1
|
||||
#else
|
||||
#define ETL_PACKED_CLASS(class_type) class class_type
|
||||
#define ETL_PACKED_STRUCT(struct_type) struct struct_type
|
||||
#define ETL_END_PACKED
|
||||
#define ETL_HAS_PACKED 0
|
||||
#endif
|
||||
|
||||
//*************************************
|
||||
// Check for availability of certain builtins
|
||||
#include "profiles/determine_builtin_support.h"
|
||||
@ -538,6 +573,7 @@ namespace etl
|
||||
static ETL_CONSTANT bool has_8bit_types = (ETL_USING_8BIT_TYPES == 1);
|
||||
static ETL_CONSTANT bool has_64bit_types = (ETL_USING_64BIT_TYPES == 1);
|
||||
static ETL_CONSTANT bool has_atomic = (ETL_HAS_ATOMIC == 1);
|
||||
static ETL_CONSTANT bool has_atomic_always_lock_free = (ETL_HAS_ATOMIC_ALWAYS_LOCK_FREE == 1);
|
||||
static ETL_CONSTANT bool has_nullptr = (ETL_HAS_NULLPTR == 1);
|
||||
static ETL_CONSTANT bool has_char8_t = (ETL_HAS_CHAR8_T == 1);
|
||||
static ETL_CONSTANT bool has_native_char8_t = (ETL_HAS_NATIVE_CHAR8_T == 1);
|
||||
@ -552,6 +588,7 @@ namespace etl
|
||||
static ETL_CONSTANT bool has_mutable_array_view = (ETL_HAS_MUTABLE_ARRAY_VIEW == 1);
|
||||
static ETL_CONSTANT bool has_ideque_repair = (ETL_HAS_IDEQUE_REPAIR == 1);
|
||||
static ETL_CONSTANT bool has_virtual_messages = (ETL_HAS_VIRTUAL_MESSAGES == 1);
|
||||
static ETL_CONSTANT bool has_packed = (ETL_HAS_PACKED == 1);
|
||||
static ETL_CONSTANT bool has_chrono_literals_day = (ETL_HAS_CHRONO_LITERALS_DAY == 1);
|
||||
static ETL_CONSTANT bool has_chrono_literals_weekday = (ETL_HAS_CHRONO_LITERALS_WEEKDAY == 1);
|
||||
static ETL_CONSTANT bool has_chrono_literals_month = (ETL_HAS_CHRONO_LITERALS_MONTH == 1);
|
||||
|
||||
@ -148,6 +148,8 @@ namespace etl
|
||||
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef typename etl::make_unsigned<ETL_BITSET_ELEMENT_TYPE>::type element_type;
|
||||
typedef element_type element_t; // Backward compatibility
|
||||
|
||||
|
||||
@ -171,6 +171,7 @@ namespace etl
|
||||
typedef TElement element_type;
|
||||
typedef TElement* pointer;
|
||||
typedef const TElement* const_pointer;
|
||||
typedef size_t size_type;
|
||||
|
||||
static ETL_CONSTANT size_t npos = etl::integral_limits<size_t>::max;
|
||||
static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits<TElement>::bits;
|
||||
@ -1937,6 +1938,8 @@ namespace etl
|
||||
typedef typename etl::private_bitset::bitset_common<Active_Bits, TElement>::span_type span_type;
|
||||
typedef typename etl::private_bitset::bitset_common<Active_Bits, TElement>::const_span_type const_span_type;
|
||||
|
||||
|
||||
|
||||
using etl::private_bitset::bitset_common<Active_Bits, TElement>::Bits_Per_Element;
|
||||
using etl::private_bitset::bitset_common<Active_Bits, TElement>::All_Set_Element;
|
||||
using etl::private_bitset::bitset_common<Active_Bits, TElement>::All_Clear_Element;
|
||||
@ -2826,6 +2829,8 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef etl::private_bitset::bitset_common<0U, unsigned char>::element_type element_type;
|
||||
typedef etl::private_bitset::bitset_common<0U, unsigned char>::span_type span_type;
|
||||
typedef etl::private_bitset::bitset_common<0U, unsigned char>::const_span_type const_span_type;
|
||||
@ -2850,6 +2855,8 @@ namespace etl
|
||||
|
||||
ETL_STATIC_ASSERT(etl::is_unsigned<TElement>::value, "The element type must be unsigned");
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef typename etl::private_bitset::bitset_common<Active_Bits, TElement>::element_type element_type;
|
||||
typedef typename etl::private_bitset::bitset_common<Active_Bits, TElement>::span_type span_type;
|
||||
typedef typename etl::private_bitset::bitset_common<Active_Bits, TElement>::const_span_type const_span_type;
|
||||
|
||||
@ -181,7 +181,7 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
unsigned char value;
|
||||
uint_least8_t value;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
|
||||
@ -181,15 +181,7 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
//***********************************************************************
|
||||
/// Normalise to a in-range month
|
||||
//***********************************************************************
|
||||
ETL_CONSTEXPR void normalise() ETL_NOEXCEPT
|
||||
{
|
||||
value = ((value % 12U) == 0U) ? 12U : value;
|
||||
}
|
||||
|
||||
unsigned char value;
|
||||
uint_least8_t value;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
@ -302,9 +294,18 @@ namespace etl
|
||||
{
|
||||
if (m1.ok() && m2.ok())
|
||||
{
|
||||
etl::chrono::months ms(static_cast<signed>(static_cast<unsigned>(m1)) -
|
||||
static_cast<signed>(static_cast<unsigned>(m2)) % 12);
|
||||
// Calculate the signed difference.
|
||||
int difference = static_cast<int>(static_cast<unsigned>(m1)) - static_cast<int>(static_cast<unsigned>(m2));
|
||||
|
||||
// Adjust for wrap-around.
|
||||
if (difference < 0)
|
||||
{
|
||||
difference += 12;
|
||||
}
|
||||
|
||||
etl::chrono::months ms(difference);
|
||||
|
||||
// Check for validity.
|
||||
if (m1 == (m2 + ms))
|
||||
{
|
||||
return ms;
|
||||
|
||||
@ -163,7 +163,7 @@ namespace etl
|
||||
// Accumulator_Bits > Chunk_Bits
|
||||
// Not Reflected
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
|
||||
static
|
||||
static ETL_CONSTEXPR14
|
||||
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && !Reflect, TAccumulator>::type
|
||||
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
|
||||
{
|
||||
@ -181,7 +181,7 @@ namespace etl
|
||||
// Accumulator_Bits > Chunk_Bits
|
||||
// Reflected
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
|
||||
static
|
||||
static ETL_CONSTEXPR14
|
||||
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && Reflect, TAccumulator>::type
|
||||
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
|
||||
{
|
||||
@ -199,7 +199,7 @@ namespace etl
|
||||
// Accumulator_Bits == Chunk_Bits
|
||||
// Not Reflected
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
|
||||
static
|
||||
static ETL_CONSTEXPR14
|
||||
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && !Reflect, TAccumulator>::type
|
||||
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
|
||||
{
|
||||
@ -216,7 +216,7 @@ namespace etl
|
||||
// Accumulator_Bits == Chunk_Bits
|
||||
// Reflected
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
|
||||
static
|
||||
static ETL_CONSTEXPR14
|
||||
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && Reflect, TAccumulator>::type
|
||||
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
|
||||
{
|
||||
@ -241,8 +241,10 @@ namespace etl
|
||||
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>
|
||||
{
|
||||
//*************************************************************************
|
||||
#if !ETL_USING_CPP11
|
||||
TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
#endif
|
||||
static ETL_CONSTANT TAccumulator table[4U] =
|
||||
{
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
|
||||
@ -250,7 +252,10 @@ namespace etl
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 2U, Chunk_Bits>::value,
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 3U, Chunk_Bits>::value
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
#endif
|
||||
if ETL_IF_CONSTEXPR(Reflect)
|
||||
{
|
||||
crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
|
||||
@ -269,6 +274,10 @@ namespace etl
|
||||
return crc;
|
||||
}
|
||||
};
|
||||
#if ETL_USING_CPP11
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
|
||||
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>::table[4U];
|
||||
#endif
|
||||
|
||||
//*********************************
|
||||
// Table size of 16.
|
||||
@ -276,8 +285,10 @@ namespace etl
|
||||
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>
|
||||
{
|
||||
//*************************************************************************
|
||||
#if !ETL_USING_CPP11
|
||||
TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
#endif
|
||||
static ETL_CONSTANT TAccumulator table[16U] =
|
||||
{
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
|
||||
@ -297,7 +308,10 @@ namespace etl
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 14U, Chunk_Bits>::value,
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 15U, Chunk_Bits>::value
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
#endif
|
||||
if ETL_IF_CONSTEXPR(Reflect)
|
||||
{
|
||||
crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
|
||||
@ -312,6 +326,10 @@ namespace etl
|
||||
return crc;
|
||||
}
|
||||
};
|
||||
#if ETL_USING_CPP11
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
|
||||
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>::table[16U];
|
||||
#endif
|
||||
|
||||
//*********************************
|
||||
// Table size of 256.
|
||||
@ -319,9 +337,11 @@ namespace etl
|
||||
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>
|
||||
{
|
||||
//*************************************************************************
|
||||
#if !ETL_USING_CPP11
|
||||
TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
static ETL_CONSTANT TAccumulator table[256U] =
|
||||
#endif
|
||||
static ETL_CONSTANT TAccumulator table[256U]=
|
||||
{
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 1U, Chunk_Bits>::value,
|
||||
@ -580,13 +600,20 @@ namespace etl
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 254U, Chunk_Bits>::value,
|
||||
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 255U, Chunk_Bits>::value
|
||||
};
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
|
||||
{
|
||||
#endif
|
||||
|
||||
crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
|
||||
|
||||
return crc;
|
||||
}
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
|
||||
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>::table[256U];
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
// CRC Policies.
|
||||
//*****************************************************************************
|
||||
@ -615,7 +642,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
accumulator_type final(accumulator_type crc) const
|
||||
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
|
||||
{
|
||||
return crc ^ TCrcParameters::Xor_Out;
|
||||
}
|
||||
@ -643,7 +670,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
accumulator_type final(accumulator_type crc) const
|
||||
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
|
||||
{
|
||||
return crc ^ TCrcParameters::Xor_Out;
|
||||
}
|
||||
@ -671,7 +698,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
accumulator_type final(accumulator_type crc) const
|
||||
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
|
||||
{
|
||||
return crc ^ TCrcParameters::Xor_Out;
|
||||
}
|
||||
@ -691,7 +718,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
crc_type()
|
||||
ETL_CONSTEXPR14 crc_type()
|
||||
{
|
||||
this->reset();
|
||||
}
|
||||
@ -702,7 +729,7 @@ namespace etl
|
||||
/// \param end End of the range.
|
||||
//*************************************************************************
|
||||
template<typename TIterator>
|
||||
crc_type(TIterator begin, const TIterator end)
|
||||
ETL_CONSTEXPR14 crc_type(TIterator begin, const TIterator end)
|
||||
{
|
||||
this->reset();
|
||||
this->add(begin, end);
|
||||
|
||||
@ -66,11 +66,11 @@ namespace etl
|
||||
//***********************************
|
||||
template <typename TDelegate, typename TReturn, typename TParam>
|
||||
struct call_if_impl
|
||||
{
|
||||
{
|
||||
etl::optional<TReturn> call_if(TParam param)
|
||||
{
|
||||
TDelegate& d = static_cast<TDelegate&>(*this);
|
||||
|
||||
TDelegate& d = static_cast<TDelegate&>(*this);
|
||||
|
||||
etl::optional<TReturn> result;
|
||||
|
||||
if (d.is_valid())
|
||||
@ -88,8 +88,8 @@ namespace etl
|
||||
{
|
||||
bool call_if()
|
||||
{
|
||||
TDelegate& d = static_cast<TDelegate&>(*this);
|
||||
|
||||
TDelegate& d = static_cast<TDelegate&>(*this);
|
||||
|
||||
if (d.is_valid())
|
||||
{
|
||||
d();
|
||||
@ -168,6 +168,22 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The tag to identify an etl::delegate.
|
||||
///\ingroup delegate
|
||||
//*****************************************************************
|
||||
struct delegate_tag
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// is_delegate
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Declaration.
|
||||
//*************************************************************************
|
||||
@ -175,14 +191,19 @@ namespace etl
|
||||
class delegate;
|
||||
|
||||
template <typename TReturn, typename TParam>
|
||||
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>
|
||||
class delegate<TReturn(TParam)> : public private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>,
|
||||
public delegate_tag
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
typedef delegate<TReturn(TParam)> delegate_type;
|
||||
|
||||
public:
|
||||
|
||||
typedef TReturn (*function_type)(TParam);
|
||||
typedef TReturn return_type;
|
||||
typedef TParam argument_type;
|
||||
|
||||
using private_delegate::call_if_impl<delegate<TReturn(TParam)>, TReturn, TParam>::call_if;
|
||||
|
||||
//*************************************************************************
|
||||
@ -204,7 +225,7 @@ namespace etl
|
||||
// Construct from a functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
|
||||
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
}
|
||||
@ -213,7 +234,7 @@ namespace etl
|
||||
// Construct from a const functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
|
||||
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
}
|
||||
@ -232,7 +253,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
static
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value &&!etl::is_same<delegate_type, TFunctor>::value, delegate>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value &&!is_delegate<TFunctor>::value, delegate>::type
|
||||
create(TFunctor& instance)
|
||||
{
|
||||
return delegate((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -243,7 +264,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
static
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
|
||||
create(const TFunctor& instance)
|
||||
{
|
||||
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
@ -330,7 +351,7 @@ namespace etl
|
||||
/// Set from Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
|
||||
set(TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -340,7 +361,7 @@ namespace etl
|
||||
/// Set from const Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
|
||||
set(const TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
@ -467,7 +488,7 @@ namespace etl
|
||||
/// Create from Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
|
||||
operator =(TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -478,7 +499,7 @@ namespace etl
|
||||
/// Create from const Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
|
||||
operator =(const TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
@ -684,6 +705,10 @@ namespace etl
|
||||
|
||||
public:
|
||||
|
||||
typedef TReturn (*function_type)(void);
|
||||
typedef TReturn return_type;
|
||||
typedef void argument_type;
|
||||
|
||||
using private_delegate::call_if_impl< delegate<TReturn(void)>, TReturn, void>::call_if;
|
||||
|
||||
//*************************************************************************
|
||||
@ -705,7 +730,7 @@ namespace etl
|
||||
// Construct from functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
|
||||
delegate(TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
}
|
||||
@ -714,7 +739,7 @@ namespace etl
|
||||
// Construct from const functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, int>::type = 0)
|
||||
delegate(const TFunctor& instance, typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, int>::type = 0)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
}
|
||||
@ -733,7 +758,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
static
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
|
||||
create(TFunctor& instance)
|
||||
{
|
||||
return delegate((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -744,7 +769,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
static
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate>::type
|
||||
create(const TFunctor& instance)
|
||||
{
|
||||
return delegate((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
@ -831,7 +856,7 @@ namespace etl
|
||||
/// Set from Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
|
||||
set(TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -841,7 +866,7 @@ namespace etl
|
||||
/// Set from const Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, void>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, void>::type
|
||||
set(const TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
@ -968,7 +993,7 @@ namespace etl
|
||||
/// Create from Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
|
||||
operator =(TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), functor_stub<TFunctor>);
|
||||
@ -979,7 +1004,7 @@ namespace etl
|
||||
/// Create from const Functor.
|
||||
//*************************************************************************
|
||||
template <typename TFunctor>
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !etl::is_same<delegate_type, TFunctor>::value, delegate&>::type
|
||||
typename etl::enable_if<etl::is_class<TFunctor>::value && !is_delegate<TFunctor>::value, delegate&>::type
|
||||
operator =(const TFunctor& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_functor_stub<TFunctor>);
|
||||
|
||||
@ -52,6 +52,7 @@ Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibl
|
||||
#include "../error_handler.h"
|
||||
#include "../exception.h"
|
||||
#include "../type_traits.h"
|
||||
#include "../function_traits.h"
|
||||
#include "../utility.h"
|
||||
#include "../optional.h"
|
||||
|
||||
@ -83,16 +84,38 @@ namespace etl
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************
|
||||
/// The tag to identify an etl::delegate.
|
||||
///\ingroup delegate
|
||||
//*****************************************************************
|
||||
struct delegate_tag
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// is_delegate
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct is_delegate : etl::bool_constant<etl::is_base_of<delegate_tag, T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T>
|
||||
inline constexpr bool is_delegate_v = is_delegate<T>::value;
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Declaration.
|
||||
//*************************************************************************
|
||||
template <typename T> class delegate;
|
||||
template <typename T>
|
||||
class delegate;
|
||||
|
||||
//*************************************************************************
|
||||
/// Specialisation.
|
||||
//*************************************************************************
|
||||
template <typename TReturn, typename... TParams>
|
||||
class delegate<TReturn(TParams...)> final
|
||||
class delegate<TReturn(TParams...)> final : public delegate_tag
|
||||
{
|
||||
public:
|
||||
|
||||
@ -111,7 +134,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Construct from lambda or functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -120,12 +143,18 @@ namespace etl
|
||||
//*************************************************************************
|
||||
// Construct from const lambda or functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Delete construction from rvalue reference lambda or functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate(TLambda&& instance) = delete;
|
||||
|
||||
//*************************************************************************
|
||||
/// Create from function (Compile time).
|
||||
//*************************************************************************
|
||||
@ -139,7 +168,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(TLambda& instance)
|
||||
{
|
||||
@ -149,7 +178,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_NODISCARD
|
||||
static ETL_CONSTEXPR14 delegate create(const TLambda& instance)
|
||||
{
|
||||
@ -257,7 +286,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Set from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 void set(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -266,7 +295,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Set from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 void set(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
@ -348,7 +377,7 @@ namespace etl
|
||||
|
||||
//*************************************************************************
|
||||
/// Execute the delegate if valid.
|
||||
/// 'void' return.
|
||||
/// 'void' return delegate.
|
||||
//*************************************************************************
|
||||
template <typename TRet = TReturn>
|
||||
ETL_CONSTEXPR14
|
||||
@ -368,7 +397,7 @@ namespace etl
|
||||
|
||||
//*************************************************************************
|
||||
/// Execute the delegate if valid.
|
||||
/// Non 'void' return.
|
||||
/// Non 'void' return delegate.
|
||||
//*************************************************************************
|
||||
template <typename TRet = TReturn>
|
||||
ETL_CONSTEXPR14
|
||||
@ -427,7 +456,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate& operator =(TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||
@ -437,7 +466,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Create from const Lambda or Functor.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !etl::is_same<etl::delegate<TReturn(TParams...)>, TLambda>::value, void>>
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value && !is_delegate<TLambda>::value, void>>
|
||||
ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance)
|
||||
{
|
||||
assign((void*)(&instance), const_lambda_stub<TLambda>);
|
||||
@ -447,6 +476,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Checks equality.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 bool operator == (const delegate& rhs) const
|
||||
{
|
||||
return invocation == rhs.invocation;
|
||||
@ -472,6 +502,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Returns <b>true</b> if the delegate is valid.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14 operator bool() const
|
||||
{
|
||||
return is_valid();
|
||||
@ -627,6 +658,92 @@ namespace etl
|
||||
//*************************************************************************
|
||||
invocation_element invocation;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a free function.
|
||||
//*************************************************************************
|
||||
template <auto Function>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate() ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(Function)>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<Function>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a functor or lambda function.
|
||||
//*************************************************************************
|
||||
template <typename TLambda, typename = etl::enable_if_t<etl::is_class<TLambda>::value, void>>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate(TLambda& instance) ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(&TLambda::operator())>::function_type;
|
||||
|
||||
return etl::delegate<function_type>(instance);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a functor, compile time.
|
||||
//*************************************************************************
|
||||
template <typename T, T& Instance>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate() ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(&T::operator())>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<T, Instance>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a member function at compile time.
|
||||
//*************************************************************************
|
||||
template <typename T, auto Method, T& Instance, typename = etl::enable_if_t<!etl::function_traits<decltype(Method)>::is_const>>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate() ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(Method)>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<T, Method, Instance>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a const member function at compile time.
|
||||
//*************************************************************************
|
||||
template <typename T, auto Method, const T& Instance, typename = etl::enable_if_t<etl::function_traits<decltype(Method)>::is_const>>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate() ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(Method)>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<T, Method, Instance>();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a member function at run time.
|
||||
//*************************************************************************
|
||||
template <typename T, auto Method>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate(T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(Method)>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<T, Method>(instance);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Make a delegate from a member function at run time.
|
||||
//*************************************************************************
|
||||
template <typename T, auto Method>
|
||||
ETL_NODISCARD
|
||||
constexpr auto make_delegate(const T& instance) ETL_NOEXCEPT
|
||||
{
|
||||
using function_type = typename etl::function_traits<decltype(Method)>::function_type;
|
||||
|
||||
return etl::delegate<function_type>::template create<T, Method>(instance);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
54
include/etl/private/tuple_element.h
Normal file
54
include/etl/private/tuple_element.h
Normal file
@ -0,0 +1,54 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2023 John Wellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_TUPLE_ELEMENT_INCLUDED
|
||||
#define ETL_TUPLE_ELEMENT_INCLUDED
|
||||
|
||||
namespace etl
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename TType>
|
||||
struct tuple_element;
|
||||
|
||||
//***************************************************************************
|
||||
template<size_t Index, typename TType>
|
||||
struct tuple_element<Index, const TType>
|
||||
{
|
||||
using type = typename etl::add_const_t<typename etl::tuple_element<Index, TType>::type>;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename TType>
|
||||
using tuple_element_t = typename tuple_element<Index, TType>::type;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
53
include/etl/private/tuple_size.h
Normal file
53
include/etl/private/tuple_size.h
Normal file
@ -0,0 +1,53 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2023 John Wellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_TUPLE_SIZE_INCLUDED
|
||||
#define ETL_TUPLE_SIZE_INCLUDED
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct tuple_size;
|
||||
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct tuple_size<const T> : etl::integral_constant<size_t, tuple_size<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T>
|
||||
inline constexpr size_t tuple_size_v = tuple_size<T>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -40,6 +40,7 @@ SOFTWARE.
|
||||
#include "../error_handler.h"
|
||||
#include "../null_type.h"
|
||||
#include "../placement_new.h"
|
||||
#include "../monostate.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -75,9 +76,7 @@ namespace etl
|
||||
/// Monostate for variants.
|
||||
///\ingroup variant
|
||||
//***************************************************************************
|
||||
struct monostate
|
||||
{
|
||||
};
|
||||
typedef etl::monostate monostate;
|
||||
|
||||
//***************************************************************************
|
||||
/// Base exception for the variant class.
|
||||
@ -480,6 +479,19 @@ namespace etl
|
||||
type_id = Type_Id_Lookup<T>::type_id;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Constructor that catches any types that are not supported.
|
||||
/// Forces a ETL_STATIC_ASSERT.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename T>
|
||||
explicit variant(etl::in_place_index_t<Index>, T const& value)
|
||||
: type_id(Index)
|
||||
{
|
||||
ETL_STATIC_ASSERT(Type_Id_Lookup<T>::type_id == Index, "Missmatched type");
|
||||
::new (static_cast<T*>(data)) T(value);
|
||||
type_id = Index;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Copy constructor.
|
||||
///\param other The other variant object to copy.
|
||||
|
||||
1020
include/etl/private/variant_select_do_operator.h
Normal file
1020
include/etl/private/variant_select_do_operator.h
Normal file
File diff suppressed because it is too large
Load Diff
1020
include/etl/private/variant_select_do_visitor.h
Normal file
1020
include/etl/private/variant_select_do_visitor.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,18 +31,20 @@ SOFTWARE.
|
||||
#include "../platform.h"
|
||||
#include "../utility.h"
|
||||
#include "../largest.h"
|
||||
#include "../nth_type.h"
|
||||
#include "../exception.h"
|
||||
#include "../type_traits.h"
|
||||
#include "../integral_limits.h"
|
||||
#include "../static_assert.h"
|
||||
#include "../alignment.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../parameter_pack.h"
|
||||
#include "../type_list.h"
|
||||
#include "../placement_new.h"
|
||||
#include "../visitor.h"
|
||||
#include "../memory.h"
|
||||
#include "../compare.h"
|
||||
#include "../initializer_list.h"
|
||||
#include "../monostate.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -66,95 +68,19 @@ namespace etl
|
||||
{
|
||||
namespace private_variant
|
||||
{
|
||||
//***************************************************************************
|
||||
// This is a copy of the normal etl::parameter_pack, but without the static_assert
|
||||
// so that the C++11 versions of do_visitor() & do_operator() do not throw a compile time error.
|
||||
//***************************************************************************
|
||||
template <typename... TTypes>
|
||||
class parameter_pack
|
||||
{
|
||||
public:
|
||||
|
||||
static constexpr size_t size = sizeof...(TTypes);
|
||||
|
||||
//***************************************************************************
|
||||
/// index_of_type
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class index_of_type
|
||||
{
|
||||
private:
|
||||
|
||||
using type = etl::remove_cvref_t<T>;
|
||||
|
||||
//***********************************
|
||||
template <typename Type, typename T1, typename... TRest>
|
||||
struct index_of_type_helper
|
||||
{
|
||||
static constexpr size_t value = etl::is_same<Type, T1>::value ? 1 : 1 + index_of_type_helper<Type, TRest...>::value;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
template <typename Type, typename T1>
|
||||
struct index_of_type_helper<Type, T1>
|
||||
{
|
||||
static constexpr size_t value = 1UL;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static_assert(etl::is_one_of<type, TTypes...>::value, "T is not in parameter pack");
|
||||
|
||||
/// The index value.
|
||||
static constexpr size_t value = index_of_type_helper<type, TTypes...>::value - 1;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// type_from_index
|
||||
//***************************************************************************
|
||||
template <size_t I>
|
||||
class type_from_index
|
||||
{
|
||||
private:
|
||||
|
||||
//***********************************
|
||||
template <size_t II, size_t N, typename T1, typename... TRest>
|
||||
struct type_from_index_helper
|
||||
{
|
||||
using type = typename etl::conditional<II == N, T1, typename type_from_index_helper<II, N + 1, TRest...>::type>::type;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
template <size_t II, size_t N, typename T1>
|
||||
struct type_from_index_helper<II, N, T1>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// Template alias
|
||||
using type = typename type_from_index_helper<I, 0, TTypes...>::type;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
template <size_t I>
|
||||
using type_from_index_t = typename type_from_index<I>::type;
|
||||
};
|
||||
|
||||
//*******************************************
|
||||
// The traits an object may have.
|
||||
//*******************************************
|
||||
static constexpr bool Copyable = true;
|
||||
static constexpr bool Copyable = true;
|
||||
static constexpr bool Non_Copyable = false;
|
||||
static constexpr bool Moveable = true;
|
||||
static constexpr bool Moveable = true;
|
||||
static constexpr bool Non_Moveable = false;
|
||||
|
||||
//*******************************************
|
||||
// The types of operations we can perform.
|
||||
//*******************************************
|
||||
static constexpr int Copy = 0;
|
||||
static constexpr int Move = 1;
|
||||
static constexpr int Copy = 0;
|
||||
static constexpr int Move = 1;
|
||||
static constexpr int Destroy = 2;
|
||||
|
||||
//*******************************************
|
||||
@ -168,7 +94,7 @@ namespace etl
|
||||
template <>
|
||||
struct operation_type<void, Non_Copyable, Non_Moveable>
|
||||
{
|
||||
static void do_operation(int , char* , const char* )
|
||||
static void do_operation(int, char*, const char*)
|
||||
{
|
||||
// This should never occur.
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
@ -195,9 +121,9 @@ namespace etl
|
||||
default:
|
||||
{
|
||||
// This should never occur.
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
assert(false);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -228,9 +154,9 @@ namespace etl
|
||||
default:
|
||||
{
|
||||
// This should never occur.
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
assert(false);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -261,9 +187,9 @@ namespace etl
|
||||
default:
|
||||
{
|
||||
// This should never occur.
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
#if defined(ETL_IN_UNIT_TEST)
|
||||
assert(false);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -320,14 +246,14 @@ namespace etl
|
||||
|
||||
//***************************************************************************
|
||||
/// variant_alternative
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename T>
|
||||
struct variant_alternative;
|
||||
|
||||
template <size_t Index, typename... TTypes>
|
||||
struct variant_alternative<Index, etl::variant<TTypes...>>
|
||||
{
|
||||
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
|
||||
using type = etl::nth_type_t<Index, TTypes...>;
|
||||
};
|
||||
|
||||
template <size_t Index, typename T>
|
||||
@ -374,13 +300,10 @@ namespace etl
|
||||
template <typename T, typename... VTypes>
|
||||
ETL_CONSTEXPR14 const T&& get(const etl::variant<VTypes...>&& v);
|
||||
|
||||
//***************************************************************************
|
||||
/// Monostate for variants.
|
||||
///\ingroup variant
|
||||
//***************************************************************************
|
||||
struct monostate
|
||||
{
|
||||
};
|
||||
#if ETL_NOT_USING_CPP17
|
||||
#include "variant_select_do_visitor.h"
|
||||
#include "variant_select_do_operator.h"
|
||||
#endif
|
||||
|
||||
constexpr bool operator >(etl::monostate, etl::monostate) noexcept { return false; }
|
||||
constexpr bool operator <(etl::monostate, etl::monostate) noexcept { return false; }
|
||||
@ -455,11 +378,6 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
//***************************************************************************
|
||||
/// The type used for ids.
|
||||
//***************************************************************************
|
||||
using type_id_t = uint_least8_t ;
|
||||
|
||||
//***************************************************************************
|
||||
/// get() is a friend function.
|
||||
//***************************************************************************
|
||||
@ -529,13 +447,13 @@ namespace etl
|
||||
// Get the index of a type.
|
||||
//*******************************************
|
||||
template <typename T>
|
||||
using index_of_type = typename etl::private_variant::parameter_pack<TTypes...>::template index_of_type<etl::remove_cvref_t<T>>;
|
||||
using index_of_type = etl::type_list_index_of_type<etl::type_list<TTypes...>, etl::remove_cvref_t<T>>;
|
||||
|
||||
//*******************************************
|
||||
// Get the type from the index.
|
||||
//*******************************************
|
||||
template <size_t Index>
|
||||
using type_from_index = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
|
||||
using type_from_index = typename etl::type_list_type_at_index<etl::type_list<TTypes...>, Index>::type;
|
||||
|
||||
public:
|
||||
|
||||
@ -546,7 +464,7 @@ namespace etl
|
||||
#include "diagnostic_uninitialized_push.h"
|
||||
ETL_CONSTEXPR14 variant()
|
||||
{
|
||||
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<0U>::type;
|
||||
using type = type_from_index<0U>;
|
||||
|
||||
default_construct_in_place<type>(data);
|
||||
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
|
||||
@ -592,7 +510,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t<Index>, TArgs&&... args)
|
||||
: type_id(Index)
|
||||
{
|
||||
using type = typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
|
||||
using type = type_from_index<Index>;
|
||||
static_assert(etl::is_one_of<type, TTypes...> ::value, "Unsupported type");
|
||||
|
||||
construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
|
||||
@ -625,7 +543,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t<Index>, std::initializer_list<U> init, TArgs&&... args)
|
||||
: type_id(Index)
|
||||
{
|
||||
using type = typename private_variant::parameter_pack<TTypes...>:: template type_from_index_t<Index>;
|
||||
using type = type_from_index<Index>;
|
||||
static_assert(etl::is_one_of<type, TTypes...> ::value, "Unsupported type");
|
||||
|
||||
construct_in_place_args<type>(data, init, etl::forward<TArgs>(args)...);
|
||||
@ -715,7 +633,7 @@ namespace etl
|
||||
|
||||
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
|
||||
|
||||
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
type_id = index_of_type<T>::value;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
@ -737,7 +655,7 @@ namespace etl
|
||||
|
||||
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
|
||||
|
||||
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
type_id = index_of_type<T>::value;
|
||||
|
||||
return *static_cast<T*>(data);
|
||||
}
|
||||
@ -747,9 +665,9 @@ namespace etl
|
||||
/// Emplace by index with variadic constructor parameters.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename... TArgs>
|
||||
typename etl::variant_alternative<Index, variant<TArgs...>>::type& emplace(TArgs&&... args)
|
||||
typename etl::variant_alternative_t<Index, variant<TTypes...>>& emplace(TArgs&&... args)
|
||||
{
|
||||
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
|
||||
static_assert(Index < sizeof...(TTypes), "Index out of range");
|
||||
|
||||
using type = type_from_index<Index>;
|
||||
|
||||
@ -769,9 +687,9 @@ namespace etl
|
||||
/// Emplace by index with variadic constructor parameters.
|
||||
//***************************************************************************
|
||||
template <size_t Index, typename U, typename... TArgs>
|
||||
typename etl::variant_alternative<Index, variant<TArgs...>>::type& emplace(std::initializer_list<U> il, TArgs&&... args)
|
||||
typename etl::variant_alternative_t<Index, variant<TTypes...>>& emplace(std::initializer_list<U> il, TArgs&&... args)
|
||||
{
|
||||
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
|
||||
static_assert(Index < sizeof...(TTypes), "Index out of range");
|
||||
|
||||
using type = type_from_index<Index>;
|
||||
|
||||
@ -803,7 +721,7 @@ namespace etl
|
||||
construct_in_place<type>(data, etl::forward<T>(value));
|
||||
|
||||
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
|
||||
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<type>::value;
|
||||
type_id = index_of_type<type>::value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -896,7 +814,7 @@ namespace etl
|
||||
template <typename T, etl::enable_if_t<is_supported_type<T>(), int> = 0>
|
||||
constexpr bool is_type() const noexcept
|
||||
{
|
||||
return (type_id == etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value);
|
||||
return (type_id == index_of_type<T>::value);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -937,7 +855,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_visitor(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_visitor(v);
|
||||
do_visitor<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -951,7 +869,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_visitor(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_visitor(v);
|
||||
do_visitor<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -965,7 +883,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_operator(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_operator(v);
|
||||
do_operator<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -979,7 +897,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_operator(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_operator(v);
|
||||
do_operator<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -996,7 +914,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_visitor(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_visitor(v);
|
||||
do_visitor<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1013,7 +931,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_visitor(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_visitor(v);
|
||||
do_visitor<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1030,7 +948,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_operator(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_operator(v);
|
||||
do_operator<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1047,7 +965,7 @@ namespace etl
|
||||
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
|
||||
do_operator(v, etl::make_index_sequence<sizeof...(TTypes)>{});
|
||||
#else
|
||||
do_operator(v);
|
||||
do_operator<sizeof...(TTypes)>(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1120,103 +1038,21 @@ namespace etl
|
||||
}
|
||||
#else
|
||||
//***************************************************************************
|
||||
/// /// Call the relevant visitor.
|
||||
/// Call the relevant visitor.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
template <size_t NTypes, typename TVisitor>
|
||||
void do_visitor(TVisitor& visitor)
|
||||
{
|
||||
switch (index())
|
||||
{
|
||||
case 0: { visitor.visit(etl::get<0>(*this)); break; }
|
||||
case 1: { visitor.visit(etl::get<1>(*this)); break; }
|
||||
case 2: { visitor.visit(etl::get<2>(*this)); break; }
|
||||
case 3: { visitor.visit(etl::get<3>(*this)); break; }
|
||||
case 4: { visitor.visit(etl::get<4>(*this)); break; }
|
||||
case 5: { visitor.visit(etl::get<5>(*this)); break; }
|
||||
case 6: { visitor.visit(etl::get<6>(*this)); break; }
|
||||
case 7: { visitor.visit(etl::get<7>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
case 8: { visitor.visit(etl::get<8>(*this)); break; }
|
||||
case 9: { visitor.visit(etl::get<9>(*this)); break; }
|
||||
case 10: { visitor.visit(etl::get<10>(*this)); break; }
|
||||
case 11: { visitor.visit(etl::get<11>(*this)); break; }
|
||||
case 12: { visitor.visit(etl::get<12>(*this)); break; }
|
||||
case 13: { visitor.visit(etl::get<13>(*this)); break; }
|
||||
case 14: { visitor.visit(etl::get<14>(*this)); break; }
|
||||
case 15: { visitor.visit(etl::get<15>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
|
||||
case 16: { visitor.visit(etl::get<16>(*this)); break; }
|
||||
case 17: { visitor.visit(etl::get<17>(*this)); break; }
|
||||
case 18: { visitor.visit(etl::get<18>(*this)); break; }
|
||||
case 19: { visitor.visit(etl::get<19>(*this)); break; }
|
||||
case 20: { visitor.visit(etl::get<20>(*this)); break; }
|
||||
case 21: { visitor.visit(etl::get<21>(*this)); break; }
|
||||
case 22: { visitor.visit(etl::get<22>(*this)); break; }
|
||||
case 23: { visitor.visit(etl::get<23>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
|
||||
case 24: { visitor.visit(etl::get<24>(*this)); break; }
|
||||
case 25: { visitor.visit(etl::get<25>(*this)); break; }
|
||||
case 26: { visitor.visit(etl::get<26>(*this)); break; }
|
||||
case 27: { visitor.visit(etl::get<27>(*this)); break; }
|
||||
case 28: { visitor.visit(etl::get<28>(*this)); break; }
|
||||
case 29: { visitor.visit(etl::get<29>(*this)); break; }
|
||||
case 30: { visitor.visit(etl::get<30>(*this)); break; }
|
||||
case 31: { visitor.visit(etl::get<31>(*this)); break; }
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
etl::private_variant::select_do_visitor<NTypes>::do_visitor(*this, visitor);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// /// Call the relevant visitor.
|
||||
/// Call the relevant visitor.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
template <size_t NTypes, typename TVisitor>
|
||||
void do_visitor(TVisitor& visitor) const
|
||||
{
|
||||
switch (index())
|
||||
{
|
||||
case 0: { visitor.visit(etl::get<0>(*this)); break; }
|
||||
case 1: { visitor.visit(etl::get<1>(*this)); break; }
|
||||
case 2: { visitor.visit(etl::get<2>(*this)); break; }
|
||||
case 3: { visitor.visit(etl::get<3>(*this)); break; }
|
||||
case 4: { visitor.visit(etl::get<4>(*this)); break; }
|
||||
case 5: { visitor.visit(etl::get<5>(*this)); break; }
|
||||
case 6: { visitor.visit(etl::get<6>(*this)); break; }
|
||||
case 7: { visitor.visit(etl::get<7>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
case 8: { visitor.visit(etl::get<8>(*this)); break; }
|
||||
case 9: { visitor.visit(etl::get<9>(*this)); break; }
|
||||
case 10: { visitor.visit(etl::get<10>(*this)); break; }
|
||||
case 11: { visitor.visit(etl::get<11>(*this)); break; }
|
||||
case 12: { visitor.visit(etl::get<12>(*this)); break; }
|
||||
case 13: { visitor.visit(etl::get<13>(*this)); break; }
|
||||
case 14: { visitor.visit(etl::get<14>(*this)); break; }
|
||||
case 15: { visitor.visit(etl::get<15>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
|
||||
case 16: { visitor.visit(etl::get<16>(*this)); break; }
|
||||
case 17: { visitor.visit(etl::get<17>(*this)); break; }
|
||||
case 18: { visitor.visit(etl::get<18>(*this)); break; }
|
||||
case 19: { visitor.visit(etl::get<19>(*this)); break; }
|
||||
case 20: { visitor.visit(etl::get<20>(*this)); break; }
|
||||
case 21: { visitor.visit(etl::get<21>(*this)); break; }
|
||||
case 22: { visitor.visit(etl::get<22>(*this)); break; }
|
||||
case 23: { visitor.visit(etl::get<23>(*this)); break; }
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
|
||||
case 24: { visitor.visit(etl::get<24>(*this)); break; }
|
||||
case 25: { visitor.visit(etl::get<25>(*this)); break; }
|
||||
case 26: { visitor.visit(etl::get<26>(*this)); break; }
|
||||
case 27: { visitor.visit(etl::get<27>(*this)); break; }
|
||||
case 28: { visitor.visit(etl::get<28>(*this)); break; }
|
||||
case 29: { visitor.visit(etl::get<29>(*this)); break; }
|
||||
case 30: { visitor.visit(etl::get<30>(*this)); break; }
|
||||
case 31: { visitor.visit(etl::get<31>(*this)); break; }
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
etl::private_variant::select_do_visitor<NTypes>::do_visitor(*this, visitor);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1282,9 +1118,9 @@ namespace etl
|
||||
}
|
||||
#else
|
||||
//***************************************************************************
|
||||
/// Call the relevant visitor.
|
||||
/// Call the relevant operator.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
template <size_t NTypes, typename TVisitor>
|
||||
void do_operator(TVisitor& visitor)
|
||||
{
|
||||
#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
@ -1301,54 +1137,13 @@ namespace etl
|
||||
|
||||
ETL_STATIC_ASSERT(sizeof...(TTypes) <= 32U, "A maximum of 32 types are allowed in this variant");
|
||||
|
||||
switch (index())
|
||||
{
|
||||
case 0: visitor(etl::get<0>(*this)); break;
|
||||
case 1: visitor(etl::get<1>(*this)); break;
|
||||
case 2: visitor(etl::get<2>(*this)); break;
|
||||
case 3: visitor(etl::get<3>(*this)); break;
|
||||
case 4: visitor(etl::get<4>(*this)); break;
|
||||
case 5: visitor(etl::get<5>(*this)); break;
|
||||
case 6: visitor(etl::get<6>(*this)); break;
|
||||
case 7: visitor(etl::get<7>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
case 8: visitor(etl::get<8>(*this)); break;
|
||||
case 9: visitor(etl::get<9>(*this)); break;
|
||||
case 10: visitor(etl::get<10>(*this)); break;
|
||||
case 11: visitor(etl::get<11>(*this)); break;
|
||||
case 12: visitor(etl::get<12>(*this)); break;
|
||||
case 13: visitor(etl::get<13>(*this)); break;
|
||||
case 14: visitor(etl::get<14>(*this)); break;
|
||||
case 15: visitor(etl::get<15>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
|
||||
case 16: visitor(etl::get<16>(*this)); break;
|
||||
case 17: visitor(etl::get<17>(*this)); break;
|
||||
case 18: visitor(etl::get<18>(*this)); break;
|
||||
case 19: visitor(etl::get<19>(*this)); break;
|
||||
case 20: visitor(etl::get<20>(*this)); break;
|
||||
case 21: visitor(etl::get<21>(*this)); break;
|
||||
case 22: visitor(etl::get<22>(*this)); break;
|
||||
case 23: visitor(etl::get<23>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
|
||||
case 24: visitor(etl::get<24>(*this)); break;
|
||||
case 25: visitor(etl::get<25>(*this)); break;
|
||||
case 26: visitor(etl::get<26>(*this)); break;
|
||||
case 27: visitor(etl::get<27>(*this)); break;
|
||||
case 28: visitor(etl::get<28>(*this)); break;
|
||||
case 29: visitor(etl::get<29>(*this)); break;
|
||||
case 30: visitor(etl::get<30>(*this)); break;
|
||||
case 31: visitor(etl::get<31>(*this)); break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
etl::private_variant::select_do_operator<NTypes>::do_operator(*this, visitor);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Call the relevant visitor.
|
||||
/// Call the relevant operator.
|
||||
//***************************************************************************
|
||||
template <typename TVisitor>
|
||||
template <size_t NTypes, typename TVisitor>
|
||||
void do_operator(TVisitor& visitor) const
|
||||
{
|
||||
#if defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
@ -1365,48 +1160,7 @@ namespace etl
|
||||
|
||||
ETL_STATIC_ASSERT(sizeof...(TTypes) <= 32U, "A maximum of 32 types are allowed in this variant");
|
||||
|
||||
switch (index())
|
||||
{
|
||||
case 0: visitor(etl::get<0>(*this)); break;
|
||||
case 1: visitor(etl::get<1>(*this)); break;
|
||||
case 2: visitor(etl::get<2>(*this)); break;
|
||||
case 3: visitor(etl::get<3>(*this)); break;
|
||||
case 4: visitor(etl::get<4>(*this)); break;
|
||||
case 5: visitor(etl::get<5>(*this)); break;
|
||||
case 6: visitor(etl::get<6>(*this)); break;
|
||||
case 7: visitor(etl::get<7>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_8_TYPES)
|
||||
case 8: visitor(etl::get<8>(*this)); break;
|
||||
case 9: visitor(etl::get<9>(*this)); break;
|
||||
case 10: visitor(etl::get<10>(*this)); break;
|
||||
case 11: visitor(etl::get<11>(*this)); break;
|
||||
case 12: visitor(etl::get<12>(*this)); break;
|
||||
case 13: visitor(etl::get<13>(*this)); break;
|
||||
case 14: visitor(etl::get<14>(*this)); break;
|
||||
case 15: visitor(etl::get<15>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_16_TYPES)
|
||||
case 16: visitor(etl::get<16>(*this)); break;
|
||||
case 17: visitor(etl::get<17>(*this)); break;
|
||||
case 18: visitor(etl::get<18>(*this)); break;
|
||||
case 19: visitor(etl::get<19>(*this)); break;
|
||||
case 20: visitor(etl::get<20>(*this)); break;
|
||||
case 21: visitor(etl::get<21>(*this)); break;
|
||||
case 22: visitor(etl::get<22>(*this)); break;
|
||||
case 23: visitor(etl::get<23>(*this)); break;
|
||||
#if !defined(ETL_VARIANT_CPP11_MAX_24_TYPES)
|
||||
case 24: visitor(etl::get<24>(*this)); break;
|
||||
case 25: visitor(etl::get<25>(*this)); break;
|
||||
case 26: visitor(etl::get<26>(*this)); break;
|
||||
case 27: visitor(etl::get<27>(*this)); break;
|
||||
case 28: visitor(etl::get<28>(*this)); break;
|
||||
case 29: visitor(etl::get<29>(*this)); break;
|
||||
case 30: visitor(etl::get<30>(*this)); break;
|
||||
case 31: visitor(etl::get<31>(*this)); break;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
etl::private_variant::select_do_operator<NTypes>::do_operator(*this, visitor);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1469,7 +1223,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
ETL_CONSTEXPR14 bool holds_alternative(const etl::variant<TTypes...>& v) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
return (Index == variant_npos) ? false : (v.index() == Index);
|
||||
}
|
||||
@ -1560,7 +1314,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
ETL_CONSTEXPR14 T& get(etl::variant<TTypes...>& v)
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -1569,7 +1323,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
ETL_CONSTEXPR14 T&& get(etl::variant<TTypes...>&& v)
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
return get<Index>(etl::move(v));
|
||||
}
|
||||
@ -1578,7 +1332,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
ETL_CONSTEXPR14 const T& get(const etl::variant<TTypes...>& v)
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
return get<Index>(v);
|
||||
}
|
||||
@ -1587,7 +1341,7 @@ namespace etl
|
||||
template <typename T, typename... TTypes>
|
||||
ETL_CONSTEXPR14 const T&& get(const etl::variant<TTypes...>&& v)
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
return get<Index>(etl::move(v));
|
||||
}
|
||||
@ -1628,7 +1382,7 @@ namespace etl
|
||||
template< class T, typename... TTypes >
|
||||
ETL_CONSTEXPR14 etl::add_pointer_t<T> get_if(etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
if ((pv != nullptr) && (pv->index() == Index))
|
||||
{
|
||||
@ -1644,7 +1398,7 @@ namespace etl
|
||||
template< typename T, typename... TTypes >
|
||||
ETL_CONSTEXPR14 etl::add_pointer_t<const T> get_if(const etl::variant<TTypes...>* pv) noexcept
|
||||
{
|
||||
constexpr size_t Index = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
|
||||
constexpr size_t Index = etl::type_list_index_of_type<etl::type_list<TTypes...>, T>::value;
|
||||
|
||||
if ((pv != nullptr) && (pv->index() == Index))
|
||||
{
|
||||
|
||||
@ -337,90 +337,107 @@ namespace etl
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
///\param args The arguments to the constructor for the new item to push to the queue.
|
||||
//*************************************************************************
|
||||
template <typename ... Args>
|
||||
void emplace(Args && ... args)
|
||||
reference emplace(Args && ... args)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(etl::forward<Args>(args)...);
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T(etl::forward<Args>(args)...);
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// Constructs a default constructed value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
//*************************************************************************
|
||||
void emplace()
|
||||
reference emplace()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T();
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T();
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
///\param value1 The argument to use to construct the item to push to the queue.
|
||||
//*************************************************************************
|
||||
template <typename T1>
|
||||
void emplace(const T1& value1)
|
||||
reference emplace(const T1& value1)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(value1);
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T(value1);
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
///\param value1 The first argument to use to construct the item to push to the queue.
|
||||
///\param value2 The second argument to use to construct the item to push to the queue.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2>
|
||||
void emplace(const T1& value1, const T2& value2)
|
||||
reference emplace(const T1& value1, const T2& value2)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(value1, value2);
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T(value1, value2);
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
///\param value1 The first argument to use to construct the item to push to the queue.
|
||||
///\param value2 The second argument to use to construct the item to push to the queue.
|
||||
///\param value3 The third argument to use to construct the item to push to the queue.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void emplace(const T1& value1, const T2& value2, const T3& value3)
|
||||
reference emplace(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(value1, value2, value3);
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T(value1, value2, value3);
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructs a value in the queue 'in place'.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full.
|
||||
///\param value The value to use to construct the item to push to the queue.
|
||||
///\param value1 The first argument to use to construct the item to push to the queue.
|
||||
///\param value2 The second argument to use to construct the item to push to the queue.
|
||||
///\param value3 The third argument to use to construct the item to push to the queue.
|
||||
///\param value4 The fourth argument to use to construct the item to push to the queue.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(value1, value2, value3, value4);
|
||||
reference value = p_buffer[in];
|
||||
::new (&value) T(value1, value2, value3, value4);
|
||||
add_in();
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -47,13 +47,13 @@ SOFTWARE.
|
||||
|
||||
namespace etl
|
||||
{
|
||||
template <size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
template <size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class queue_spsc_atomic_base
|
||||
{
|
||||
public:
|
||||
|
||||
/// The type used for determining the size of queue.
|
||||
typedef typename etl::size_type_lookup<MEMORY_MODEL>::type size_type;
|
||||
typedef typename etl::size_type_lookup<Memory_Model>::type size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the queue empty?
|
||||
@ -72,7 +72,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
size_type next_index = get_next_index(write.load(etl::memory_order_acquire), RESERVED);
|
||||
size_type next_index = get_next_index(write.load(etl::memory_order_acquire), Reserved);
|
||||
|
||||
return (next_index == read.load(etl::memory_order_acquire));
|
||||
}
|
||||
@ -94,7 +94,7 @@ namespace etl
|
||||
}
|
||||
else
|
||||
{
|
||||
n = RESERVED - read_index + write_index;
|
||||
n = Reserved - read_index + write_index;
|
||||
}
|
||||
|
||||
return n;
|
||||
@ -106,7 +106,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
size_type available() const
|
||||
{
|
||||
return RESERVED - size() - 1;
|
||||
return Reserved - size() - 1;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -114,7 +114,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return RESERVED - 1;
|
||||
return Reserved - 1;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -122,7 +122,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return RESERVED - 1;
|
||||
return Reserved - 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -130,7 +130,7 @@ namespace etl
|
||||
queue_spsc_atomic_base(size_type reserved_)
|
||||
: write(0),
|
||||
read(0),
|
||||
RESERVED(reserved_)
|
||||
Reserved(reserved_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ namespace etl
|
||||
|
||||
etl::atomic<size_type> write; ///< Where to input new data.
|
||||
etl::atomic<size_type> read; ///< Where to get the oldest data.
|
||||
const size_type RESERVED; ///< The maximum number of items in the queue.
|
||||
const size_type Reserved; ///< The maximum number of items in the queue.
|
||||
|
||||
private:
|
||||
|
||||
@ -182,12 +182,12 @@ namespace etl
|
||||
/// This queue supports concurrent access by one producer and one consumer.
|
||||
/// \tparam T The type of value that the queue_spsc_atomic holds.
|
||||
//***************************************************************************
|
||||
template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class iqueue_spsc_atomic : public queue_spsc_atomic_base<MEMORY_MODEL>
|
||||
template <typename T, const size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class iqueue_spsc_atomic : public queue_spsc_atomic_base<Memory_Model>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename etl::queue_spsc_atomic_base<MEMORY_MODEL> base_t;
|
||||
typedef typename etl::queue_spsc_atomic_base<Memory_Model> base_t;
|
||||
|
||||
public:
|
||||
|
||||
@ -201,7 +201,7 @@ namespace etl
|
||||
|
||||
using base_t::write;
|
||||
using base_t::read;
|
||||
using base_t::RESERVED;
|
||||
using base_t::Reserved;
|
||||
using base_t::get_next_index;
|
||||
|
||||
//*************************************************************************
|
||||
@ -210,7 +210,7 @@ namespace etl
|
||||
bool push(const_reference value)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -232,7 +232,7 @@ namespace etl
|
||||
bool push(rvalue_reference value)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -257,7 +257,7 @@ namespace etl
|
||||
bool emplace(Args&&... args)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -279,7 +279,7 @@ namespace etl
|
||||
bool emplace()
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -302,7 +302,7 @@ namespace etl
|
||||
bool emplace(const T1& value1)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -325,7 +325,7 @@ namespace etl
|
||||
bool emplace(const T1& value1, const T2& value2)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -348,7 +348,7 @@ namespace etl
|
||||
bool emplace(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -371,7 +371,7 @@ namespace etl
|
||||
bool emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
size_type write_index = write.load(etl::memory_order_relaxed);
|
||||
size_type next_index = get_next_index(write_index, RESERVED);
|
||||
size_type next_index = get_next_index(write_index, Reserved);
|
||||
|
||||
if (next_index != read.load(etl::memory_order_acquire))
|
||||
{
|
||||
@ -418,7 +418,7 @@ namespace etl
|
||||
return false;
|
||||
}
|
||||
|
||||
size_type next_index = get_next_index(read_index, RESERVED);
|
||||
size_type next_index = get_next_index(read_index, Reserved);
|
||||
|
||||
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_LOCKABLE_FORCE_CPP03_IMPLEMENTATION)
|
||||
value = etl::move(p_buffer[read_index]);
|
||||
@ -446,7 +446,7 @@ namespace etl
|
||||
return false;
|
||||
}
|
||||
|
||||
size_type next_index = get_next_index(read_index, RESERVED);
|
||||
size_type next_index = get_next_index(read_index, Reserved);
|
||||
|
||||
p_buffer[read_index].~T();
|
||||
|
||||
@ -518,15 +518,15 @@ namespace etl
|
||||
/// A fixed capacity spsc queue.
|
||||
/// This queue supports concurrent access by one producer and one consumer.
|
||||
/// \tparam T The type this queue should support.
|
||||
/// \tparam SIZE The maximum capacity of the queue.
|
||||
/// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables.
|
||||
/// \tparam Size The maximum capacity of the queue.
|
||||
/// \tparam Memory_Model The memory model for the queue. Determines the type of the internal counter variables.
|
||||
//***************************************************************************
|
||||
template <typename T, size_t SIZE, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class queue_spsc_atomic : public iqueue_spsc_atomic<T, MEMORY_MODEL>
|
||||
template <typename T, size_t Size, const size_t Memory_Model = etl::memory_model::MEMORY_MODEL_LARGE>
|
||||
class queue_spsc_atomic : public iqueue_spsc_atomic<T, Memory_Model>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef typename etl::iqueue_spsc_atomic<T, MEMORY_MODEL> base_t;
|
||||
typedef typename etl::iqueue_spsc_atomic<T, Memory_Model> base_t;
|
||||
|
||||
public:
|
||||
|
||||
@ -534,19 +534,19 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
static ETL_CONSTANT size_type RESERVED_SIZE = size_type(SIZE + 1);
|
||||
static ETL_CONSTANT size_type Reserved_Size = size_type(Size + 1);
|
||||
|
||||
public:
|
||||
|
||||
ETL_STATIC_ASSERT((SIZE <= (etl::integral_limits<size_type>::max - 1)), "Size too large for memory model");
|
||||
ETL_STATIC_ASSERT((Size <= (etl::integral_limits<size_type>::max - 1)), "Size too large for memory model");
|
||||
|
||||
static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE);
|
||||
static ETL_CONSTANT size_type MAX_SIZE = size_type(Size);
|
||||
|
||||
//*************************************************************************
|
||||
/// Default constructor.
|
||||
//*************************************************************************
|
||||
queue_spsc_atomic()
|
||||
: base_t(reinterpret_cast<T*>(&buffer[0]), RESERVED_SIZE)
|
||||
: base_t(reinterpret_cast<T*>(&buffer[0]), Reserved_Size)
|
||||
{
|
||||
}
|
||||
|
||||
@ -561,11 +561,11 @@ namespace etl
|
||||
private:
|
||||
|
||||
/// The uninitialised buffer of T used in the queue_spsc.
|
||||
typename etl::aligned_storage<sizeof(T), etl::alignment_of<T>::value>::type buffer[RESERVED_SIZE];
|
||||
typename etl::aligned_storage<sizeof(T), etl::alignment_of<T>::value>::type buffer[Reserved_Size];
|
||||
};
|
||||
|
||||
template <typename T, size_t SIZE, const size_t MEMORY_MODEL>
|
||||
ETL_CONSTANT typename queue_spsc_atomic<T, SIZE, MEMORY_MODEL>::size_type queue_spsc_atomic<T, SIZE, MEMORY_MODEL>::MAX_SIZE;
|
||||
template <typename T, size_t Size, const size_t Memory_Model>
|
||||
ETL_CONSTANT typename queue_spsc_atomic<T, Size, Memory_Model>::size_type queue_spsc_atomic<T, Size, Memory_Model>::MAX_SIZE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -822,8 +822,8 @@ namespace etl
|
||||
|
||||
private:
|
||||
|
||||
queue_spsc_isr(const queue_spsc_isr&);
|
||||
queue_spsc_isr& operator = (const queue_spsc_isr&);
|
||||
queue_spsc_isr(const queue_spsc_isr&) ETL_DELETE;
|
||||
queue_spsc_isr& operator = (const queue_spsc_isr&) ETL_DELETE;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
queue_spsc_isr(queue_spsc_isr&&) = delete;
|
||||
|
||||
@ -35,6 +35,8 @@ SOFTWARE.
|
||||
#include "static_assert.h"
|
||||
#include "gcd.h"
|
||||
|
||||
#include "type_traits.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -138,6 +140,26 @@ namespace etl
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
|
||||
|
||||
template<typename R1, typename R2>
|
||||
inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
|
||||
#endif
|
||||
|
||||
//***********************************************************************
|
||||
/// Predefined ration types.
|
||||
//***********************************************************************
|
||||
@ -182,7 +204,93 @@ namespace etl
|
||||
typedef ratio<169, 239> ratio_1_over_root2;
|
||||
|
||||
/// An approximation of e.
|
||||
typedef ratio<106, 39> ratio_e;
|
||||
typedef ratio<326, 120> ratio_e;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace private_ratio
|
||||
{
|
||||
// Primary template for GCD calculation
|
||||
template <typename T, T A, T B, bool = (B == 0)>
|
||||
struct ratio_gcd;
|
||||
|
||||
// Specialisation for the case when B is not zero
|
||||
template <typename T, T A, T B>
|
||||
struct ratio_gcd<T, A, B, false>
|
||||
{
|
||||
static constexpr T value = ratio_gcd<T, B, A % B>::value;
|
||||
};
|
||||
|
||||
// Specialisation for the case when B is zero
|
||||
template <typename T, T A, T B>
|
||||
struct ratio_gcd<T, A, B, true>
|
||||
{
|
||||
static constexpr T value = (A < 0) ? -A : A;
|
||||
};
|
||||
|
||||
// Primary template for LCM calculation
|
||||
template <typename T, T A, T B>
|
||||
struct ratio_lcm
|
||||
{
|
||||
private:
|
||||
|
||||
static constexpr T product = ((A * B) < 0) ? -(A * B) : A * B;
|
||||
|
||||
public:
|
||||
|
||||
static constexpr T value = product / ratio_gcd<T, A, B>::value;
|
||||
};
|
||||
|
||||
template<typename R1>
|
||||
struct ratio_reduce
|
||||
{
|
||||
private:
|
||||
|
||||
static ETL_CONSTEXPR11 intmax_t gcd = etl::private_ratio::ratio_gcd<intmax_t, R1::num, R1::den>::value;
|
||||
|
||||
public:
|
||||
|
||||
using type = ratio<R1::num / gcd, R1::den / gcd>;
|
||||
};
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_add
|
||||
{
|
||||
private:
|
||||
|
||||
static ETL_CONSTEXPR11 intmax_t lcm = etl::private_ratio::ratio_lcm<intmax_t, R1::den, R2::den>::value;
|
||||
|
||||
public:
|
||||
|
||||
using type = typename ratio_reduce<ratio<R1::num * lcm / R1::den + R2::num * lcm / R2::den, lcm>>::type;
|
||||
};
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_subtract
|
||||
{
|
||||
public:
|
||||
using type = typename ratio_add<R1, ratio<-R2::num, R2::den>>::type;
|
||||
};
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_multiply
|
||||
{
|
||||
private:
|
||||
static ETL_CONSTEXPR11 intmax_t gcd1 = etl::private_ratio::ratio_gcd<intmax_t, R1::num, R2::den>::value;
|
||||
static ETL_CONSTEXPR11 intmax_t gcd2 = etl::private_ratio::ratio_gcd<intmax_t, R2::num, R1::den>::value;
|
||||
|
||||
public:
|
||||
using type = ratio<(R1::num / gcd1) * (R2::num / gcd2), (R1::den / gcd2) * (R2::den / gcd1)>;
|
||||
};
|
||||
|
||||
template<typename R1, typename R2>
|
||||
struct ratio_divide
|
||||
{
|
||||
public:
|
||||
using type = typename ratio_multiply<R1, ratio<R2::den, R2::num>>::type;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -46,14 +46,13 @@ namespace etl
|
||||
//*****************************************************************************
|
||||
/// A set of rounding algorithms for scaled integrals.
|
||||
/// \tparam T The integral type.
|
||||
/// \tparam SCALING The scaling factor.
|
||||
/// \tparam Scaling The scaling factor.
|
||||
///
|
||||
/// \example For emulating fixed point of two decimal places we could use a
|
||||
/// scaling factor of '100'. To round the result of scaled int calculations
|
||||
/// using 'Banker's Rounding' we would define this.
|
||||
/// \code
|
||||
/// typedef etl::scaled_rounding<int, 100> Rounding;
|
||||
/// int final_result = Rounding::round_half_even_unscaled(accumulated_result);
|
||||
/// int final_result = round_half_even_unscaled<100>(accumulated_result);
|
||||
/// \endcode
|
||||
/// \link http://www.clivemaxfield.com/diycalculator/sp-round.shtml
|
||||
//*****************************************************************************
|
||||
@ -63,19 +62,25 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_ceiling_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_ceiling_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (Scaling == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(SCALING)) / scale_t(SCALING));
|
||||
return T((value + scale_t(Scaling - 1U)) / scale_t(Scaling));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(value / scale_t(SCALING));
|
||||
return T(value / scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,12 +89,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_ceiling_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_ceiling_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return round_ceiling_unscaled<SCALING>(value) * scale_t(SCALING);
|
||||
return round_ceiling_unscaled<Scaling>(value) * scale_t(Scaling);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -97,19 +104,24 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_floor_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_floor_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
if (Scaling == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T(value / scale_t(SCALING));
|
||||
return T(value / scale_t(Scaling));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING)) / scale_t(SCALING));
|
||||
return T((value - scale_t(Scaling - 1)) / scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,12 +130,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_floor_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_floor_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_floor_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_floor_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -132,20 +146,27 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_up_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_up_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
if (Scaling == 1)
|
||||
{
|
||||
return T((value + scale_t(SCALING / 2U)) / scale_t(SCALING));
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING / 2U)) / scale_t(SCALING));
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(Scaling / 2U)) / scale_t(Scaling));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(Scaling / 2U)) / scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,12 +176,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_up_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_up_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_up_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_half_up_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -169,20 +192,25 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_down_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_down_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (Scaling == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
|
||||
return T((value + scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
|
||||
return T((value - scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,12 +220,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_down_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_down_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_down_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_half_down_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -205,13 +235,21 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_zero_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_zero_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(value / scale_t(SCALING));
|
||||
if (Scaling == 1)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(value / scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -219,46 +257,49 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_zero_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_zero_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_zero_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_zero_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward infinity.
|
||||
/// Round twords infinity or away from zero.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_infinity_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_infinity_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(SCALING)) / scale_t(SCALING));
|
||||
return etl::round_ceiling_unscaled<Scaling>(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING)) / scale_t(SCALING));
|
||||
return etl::round_floor_unscaled<Scaling>(value);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward infinity.
|
||||
/// Round twords infinity or away from zero.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_infinity_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_infinity_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_infinity_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_infinity_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -267,28 +308,36 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_even_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_even_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
|
||||
if (Scaling == 1)
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(SCALING)) & 1U)
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_down_unscaled<SCALING>(value));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(Scaling)) & 1U)
|
||||
{
|
||||
return T(round_half_up_unscaled<Scaling>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_down_unscaled<Scaling>(value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<Scaling>(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,12 +347,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_even_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_even_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_even_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_half_even_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -312,28 +363,36 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_odd_unscaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_odd_unscaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
|
||||
if (Scaling == 1)
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(SCALING)) & 1U)
|
||||
{
|
||||
return T(round_half_down_unscaled<SCALING>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(Scaling)) & 1U)
|
||||
{
|
||||
return T(round_half_down_unscaled<Scaling>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<Scaling>(value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<Scaling>(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,12 +402,14 @@ namespace etl
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <uint32_t SCALING, typename T>
|
||||
T round_half_odd_scaled(T value)
|
||||
template <uint32_t Scaling, typename T>
|
||||
ETL_NODISCARD
|
||||
ETL_CONSTEXPR14
|
||||
T round_half_odd_scaled(T value) ETL_NOEXCEPT
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_odd_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
return T(round_half_odd_unscaled<Scaling>(value) * scale_t(Scaling));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
172
include/etl/singleton_base.h
Normal file
172
include/etl/singleton_base.h
Normal file
@ -0,0 +1,172 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2019 John Wellbelove
|
||||
Copyright(c) 2024 BMW AG
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_SINGLETON_BASE_INCLUDED
|
||||
#define ETL_SINGLETON_BASE_INCLUDED
|
||||
|
||||
///\defgroup singleton_base singleton_base
|
||||
/// Templated version of the singleton pattern, implemented as base class
|
||||
/// for singletons.
|
||||
///\ingroup etl
|
||||
|
||||
#include "platform.h"
|
||||
#include "error_handler.h"
|
||||
#include "nullptr.h"
|
||||
#include "file_error_numbers.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*************************************************************************
|
||||
/// Base singleton error exception.
|
||||
//*************************************************************************
|
||||
class singleton_base_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Singleton not created error exception.
|
||||
//*************************************************************************
|
||||
class singleton_base_not_created : public etl::singleton_base_exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_not_created(string_type file_name_, numeric_type line_number_)
|
||||
: singleton_base_exception(ETL_ERROR_TEXT("singleton_base:not created", ETL_SINGLETON_BASE_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Singleton instance already exists.
|
||||
//*************************************************************************
|
||||
class singleton_base_already_created : public etl::singleton_base_exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_already_created(string_type file_name_, numeric_type line_number_)
|
||||
: singleton_base_exception(ETL_ERROR_TEXT("singleton_base:already created", ETL_SINGLETON_BASE_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// Base class for singletons.
|
||||
/// \tparam T Any type that wants to expose the instance() interface.
|
||||
///
|
||||
/// This class is designed to work as a generic base class for any class that wants to
|
||||
/// provide a singleton interface. It'll also work for classes that do not have a
|
||||
/// default constructor.
|
||||
///
|
||||
/// Usage example:
|
||||
///
|
||||
/// class Origin
|
||||
/// : singleton<Origin>
|
||||
/// {
|
||||
/// public:
|
||||
/// Origin(int x, int y)
|
||||
/// : singleton<Origin>(*this)
|
||||
/// {}
|
||||
///
|
||||
/// int getX() const;
|
||||
/// } theOrigin(0, 0);
|
||||
///
|
||||
/// int x = Origin::instance().getX();
|
||||
///
|
||||
///
|
||||
/// Note:
|
||||
///
|
||||
/// It is important that a call to instance() will not create the instance of the class. It needs
|
||||
/// to be created by the user before calling instance(). This way, the user has better control
|
||||
/// over the instance lifetime instead of e.g. lazy initialization.
|
||||
//***********************************************************************
|
||||
template <typename T>
|
||||
class singleton_base
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************************************************
|
||||
// Returns a reference to the instance.
|
||||
//***********************************************************************
|
||||
static T& instance()
|
||||
{
|
||||
ETL_ASSERT(m_self != ETL_NULLPTR, ETL_ERROR(etl::singleton_base_not_created));
|
||||
|
||||
return *m_self;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Returns whether an instance has been attached to singleton<T> or not.
|
||||
//***********************************************************************
|
||||
static bool is_valid()
|
||||
{
|
||||
return (m_self != ETL_NULLPTR);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//***********************************************************************
|
||||
/// Constructs the instance of singleton.
|
||||
/// theInstance Reference to T, which will be returned when instance() is called.
|
||||
//***********************************************************************
|
||||
explicit singleton_base(T& theInstance)
|
||||
{
|
||||
ETL_ASSERT(m_self == ETL_NULLPTR, ETL_ERROR(etl::singleton_base_already_created));
|
||||
|
||||
m_self = &theInstance;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Removes the internal reference to the instance passed in the constructor.
|
||||
//***********************************************************************
|
||||
~singleton_base()
|
||||
{
|
||||
m_self = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static T* m_self;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// No violation of one definition rule as this is a class template
|
||||
//***********************************************************************
|
||||
template<class T>
|
||||
T* singleton_base<T>::m_self = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -32,6 +32,10 @@ SOFTWARE.
|
||||
#define ETL_SPAN_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "alignment.h"
|
||||
#include "iterator.h"
|
||||
#include "algorithm.h"
|
||||
#include "circular_iterator.h"
|
||||
@ -46,20 +50,63 @@ SOFTWARE.
|
||||
|
||||
#include "private/dynamic_extent.h"
|
||||
|
||||
#if ETL_USING_CPP20 && ETL_USING_STL
|
||||
#include <span>
|
||||
#endif
|
||||
|
||||
///\defgroup span span
|
||||
///\ingroup containers
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
// Tag to indicate a class is a span.
|
||||
//***************************************************************************
|
||||
class span_tag {};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup span
|
||||
/// Exception base for span
|
||||
//***************************************************************************
|
||||
class span_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
span_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup span
|
||||
/// Bad alignment exception.
|
||||
//***************************************************************************
|
||||
class span_alignment_exception : public span_exception
|
||||
{
|
||||
public:
|
||||
|
||||
span_alignment_exception(string_type file_name_, numeric_type line_number_)
|
||||
: span_exception(ETL_ERROR_TEXT("span:alignment", ETL_SPAN_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup span
|
||||
/// span size exception.
|
||||
//***************************************************************************
|
||||
class span_size_mismatch : public span_exception
|
||||
{
|
||||
public:
|
||||
|
||||
span_size_mismatch(string_type file_name_, numeric_type line_number_)
|
||||
: span_exception(ETL_ERROR_TEXT("span:size", ETL_SPAN_FILE_ID"B"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Span - Fixed Extent
|
||||
//***************************************************************************
|
||||
template <typename T, size_t Extent = etl::dynamic_extent>
|
||||
class span
|
||||
class span : public span_tag
|
||||
{
|
||||
public:
|
||||
|
||||
@ -71,8 +118,10 @@ namespace etl
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
typedef T* iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
typedef etl::circular_iterator<pointer> circular_iterator;
|
||||
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
|
||||
@ -84,7 +133,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator, typename TSize>
|
||||
ETL_CONSTEXPR explicit span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT
|
||||
: pbegin(etl::addressof(*begin_))
|
||||
: pbegin(etl::to_address(begin_))
|
||||
{
|
||||
}
|
||||
|
||||
@ -93,28 +142,40 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR explicit span(const TIterator begin_, const TIterator /*end_*/)
|
||||
: pbegin(etl::addressof(*begin_))
|
||||
: pbegin(etl::to_address(begin_))
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Construct from C array
|
||||
//*************************************************************************
|
||||
template<size_t Array_Size>
|
||||
#if ETL_USING_CPP11
|
||||
template<size_t Array_Size, typename = typename etl::enable_if<(Array_Size == Extent), void>::type>
|
||||
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
|
||||
: pbegin(begin_)
|
||||
{
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
/// Construct from C array
|
||||
//*************************************************************************
|
||||
template<size_t Array_Size>
|
||||
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size], typename etl::enable_if<(Array_Size == Extent), void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(begin_)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Construct from a container or other type that supports
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
|
||||
template <typename TContainer, typename = typename etl::enable_if<!etl::is_base_of<span_tag, etl::remove_reference_t<TContainer>>::value &&
|
||||
!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
|
||||
!etl::is_array<etl::remove_reference_t<TContainer>>::value&&
|
||||
etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
|
||||
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
{
|
||||
}
|
||||
@ -124,7 +185,8 @@ namespace etl
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer>
|
||||
span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
span(TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_array<TContainer>::value &&
|
||||
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
@ -136,9 +198,10 @@ namespace etl
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer>
|
||||
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_array<TContainer>::value&&
|
||||
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
|
||||
span(const TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_array<TContainer>::value&&
|
||||
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
{
|
||||
}
|
||||
@ -154,13 +217,25 @@ namespace etl
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor
|
||||
/// From fixed extent span.
|
||||
//*************************************************************************
|
||||
template <typename U, size_t N>
|
||||
ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<(Extent == etl::dynamic_extent) || (N == etl::dynamic_extent) || (N == Extent), void>::type) ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR span(const etl::span<U, N>& other, typename etl::enable_if<N == Extent, void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(other.data())
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy constructor
|
||||
/// From dynamic extent span.
|
||||
//*************************************************************************
|
||||
template <typename U, size_t N>
|
||||
ETL_CONSTEXPR14 span(const etl::span<U, N>& other, typename etl::enable_if<N == etl::dynamic_extent, void>::type* = 0)
|
||||
: pbegin(other.data())
|
||||
{
|
||||
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reference to the first element.
|
||||
//*************************************************************************
|
||||
@ -185,6 +260,14 @@ namespace etl
|
||||
return pbegin;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const iterator to the beginning of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
|
||||
{
|
||||
return pbegin;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns an iterator to the beginning of the span.
|
||||
//*************************************************************************
|
||||
@ -201,6 +284,14 @@ namespace etl
|
||||
return circular_iterator(begin(), end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
|
||||
{
|
||||
return (pbegin + Extent);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns an iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
@ -209,6 +300,14 @@ namespace etl
|
||||
return (pbegin + Extent);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Returns a const reverse iterator to the reverse beginning of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
|
||||
{
|
||||
return const_reverse_iterator((pbegin + Extent));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Returns an reverse iterator to the reverse beginning of the span.
|
||||
//*************************************************************************
|
||||
@ -225,6 +324,14 @@ namespace etl
|
||||
return reverse_circular_iterator(rbegin(), rend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const reverse iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
|
||||
{
|
||||
return const_reverse_iterator(pbegin);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reverse iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
@ -238,7 +345,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
return Extent == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -272,6 +379,26 @@ namespace etl
|
||||
{
|
||||
pbegin = other.pbegin;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reference to the value at index 'i'.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
|
||||
|
||||
return pbegin[i];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const reference to the value at index 'i'.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
|
||||
|
||||
return pbegin[i];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -328,14 +455,14 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
|
||||
ETL_NODISCARD ETL_CONSTEXPR
|
||||
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
|
||||
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
|
||||
{
|
||||
// If Extent is static, check that OFFSET is within the original span
|
||||
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? OFFSET <= Extent : true, "OFFSET is not within the original span");
|
||||
|
||||
// If count is also static, check that OFFSET + COUNT is within the original span
|
||||
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
|
||||
|
||||
|
||||
return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, (pbegin + Extent))
|
||||
: etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
|
||||
}
|
||||
@ -351,7 +478,7 @@ namespace etl
|
||||
|
||||
// If count is also static, check that OFFSET + COUNT is within the original span
|
||||
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
|
||||
|
||||
|
||||
if (COUNT == etl::dynamic_extent)
|
||||
{
|
||||
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET)>(pbegin + OFFSET, (pbegin + Extent));
|
||||
@ -372,16 +499,48 @@ namespace etl
|
||||
: etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Moves the pointer to the first element of the span further by a specified number of elements.
|
||||
///\tparam elements Number of elements to move forward
|
||||
//*************************************************************************
|
||||
void advance(size_t elements) ETL_NOEXCEPT
|
||||
{
|
||||
elements = etl::min(elements, size());
|
||||
pbegin += elements;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Reinterpret the span as a span with different element type.
|
||||
//*************************************************************************
|
||||
template<typename TNew>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<TNew, etl::dynamic_extent> reinterpret_as() const
|
||||
{
|
||||
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TNew>::value>(pbegin), ETL_ERROR(span_alignment_exception));
|
||||
|
||||
return etl::span<TNew, etl::dynamic_extent>(reinterpret_cast<TNew*>(pbegin),
|
||||
Extent * sizeof(element_type) / sizeof(TNew));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pointer pbegin;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Pseudo constructor for constructing from C array without explicitly
|
||||
/// specifying type and size
|
||||
//*************************************************************************
|
||||
template <typename T, size_t Extent>
|
||||
ETL_CONSTEXPR span<T, Extent> make_span(T (&data)[Extent])
|
||||
{
|
||||
return span<T, Extent>(data);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Span - Dynamic Extent
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class span<T, etl::dynamic_extent>
|
||||
class span<T, etl::dynamic_extent> : public span_tag
|
||||
{
|
||||
public:
|
||||
|
||||
@ -392,9 +551,11 @@ namespace etl
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
typedef T* iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
typedef etl::circular_iterator<pointer> circular_iterator;
|
||||
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
|
||||
@ -415,8 +576,8 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator, typename TSize>
|
||||
ETL_CONSTEXPR span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
|
||||
: pbegin(etl::addressof(*begin_))
|
||||
, pend(etl::addressof(*begin_) + size_)
|
||||
: pbegin(etl::to_address(begin_))
|
||||
, pend(etl::to_address(begin_) + size_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -425,8 +586,8 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
ETL_CONSTEXPR span(const TIterator begin_, const TIterator end_)
|
||||
: pbegin(etl::addressof(*begin_))
|
||||
, pend(etl::addressof(*begin_) + etl::distance(begin_, end_))
|
||||
: pbegin(etl::to_address(begin_))
|
||||
, pend(etl::to_address(begin_) + etl::distance(begin_, end_))
|
||||
{
|
||||
}
|
||||
|
||||
@ -445,10 +606,11 @@ namespace etl
|
||||
/// Construct from a container or other type that supports
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
|
||||
template <typename TContainer, typename = typename etl::enable_if<!etl::is_base_of<span_tag, etl::remove_reference_t<TContainer>>::value &&
|
||||
!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
|
||||
!etl::is_array<etl::remove_reference_t<TContainer>>::value &&
|
||||
etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
|
||||
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
|
||||
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
, pend(a.data() + a.size())
|
||||
{
|
||||
@ -459,7 +621,8 @@ namespace etl
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer>
|
||||
ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_array<TContainer>::value &&
|
||||
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
@ -472,7 +635,8 @@ namespace etl
|
||||
/// data() and size() member functions.
|
||||
//*************************************************************************
|
||||
template <typename TContainer>
|
||||
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_base_of<span_tag, typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
|
||||
!etl::is_array<TContainer>::value &&
|
||||
etl::is_same<typename etl::remove_cv<T>::type, typename etl::remove_cv<typename etl::remove_reference<TContainer>::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT
|
||||
: pbegin(a.data())
|
||||
@ -524,6 +688,14 @@ namespace etl
|
||||
return pbegin;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const iterator to the beginning of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
|
||||
{
|
||||
return pbegin;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns an iterator to the beginning of the span.
|
||||
//*************************************************************************
|
||||
@ -540,6 +712,14 @@ namespace etl
|
||||
return circular_iterator(begin(), end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
|
||||
{
|
||||
return pend;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns an iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
@ -556,6 +736,14 @@ namespace etl
|
||||
return reverse_iterator(pend);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Returns a const reverse iterator to the reverse beginning of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
|
||||
{
|
||||
return const_reverse_iterator(pend);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reverse circular iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
@ -564,6 +752,14 @@ namespace etl
|
||||
return reverse_circular_iterator(rbegin(), rend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const reverse iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
|
||||
{
|
||||
return const_reverse_iterator(pbegin);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reverse iterator to the end of the span.
|
||||
//*************************************************************************
|
||||
@ -614,6 +810,26 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reference to the value at index 'i'.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
|
||||
|
||||
return pbegin[i];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a const reference to the value at index 'i'.
|
||||
//*************************************************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(array_out_of_range));
|
||||
|
||||
return pbegin[i];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns a reference to the indexed value.
|
||||
//*************************************************************************
|
||||
@ -662,7 +878,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
|
||||
ETL_NODISCARD ETL_CONSTEXPR
|
||||
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const ETL_NOEXCEPT
|
||||
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const ETL_NOEXCEPT
|
||||
{
|
||||
return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pend)
|
||||
: etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
|
||||
@ -694,12 +910,54 @@ namespace etl
|
||||
: etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Moves the pointer to the first element of the span further by a specified number of elements.
|
||||
///\tparam elements Number of elements to move forward
|
||||
//*************************************************************************
|
||||
void advance(size_t elements) ETL_NOEXCEPT
|
||||
{
|
||||
elements = etl::min(elements, size());
|
||||
pbegin += elements;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Reinterpret the span as a span with different element type.
|
||||
//*************************************************************************
|
||||
template<typename TNew>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<TNew, etl::dynamic_extent> reinterpret_as() const
|
||||
{
|
||||
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TNew>::value>(pbegin), ETL_ERROR(span_alignment_exception));
|
||||
|
||||
return etl::span<TNew, etl::dynamic_extent>(reinterpret_cast<TNew*>(pbegin),
|
||||
(pend - pbegin) * sizeof(element_type) / sizeof(TNew));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pointer pbegin;
|
||||
pointer pend;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Pseudo constructor for constructing from container without explicitly
|
||||
/// specifying type and size
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR span<typename T::value_type, etl::dynamic_extent> make_span(T& data)
|
||||
{
|
||||
return span<typename T::value_type, etl::dynamic_extent>(data);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Pseudo constructor for constructing from const container without
|
||||
/// explicitly specifying type and size
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
ETL_CONSTEXPR span<typename T::value_type const, etl::dynamic_extent> make_span(const T& data)
|
||||
{
|
||||
return span<typename T::value_type const, etl::dynamic_extent>(data);
|
||||
}
|
||||
|
||||
template <typename T, size_t Extent>
|
||||
ETL_CONSTANT size_t span<T, Extent>::extent;
|
||||
|
||||
@ -746,6 +1004,33 @@ namespace etl
|
||||
etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Copy complete element data from one span to another. If the destination
|
||||
/// span is bigger than the source span, only the initial part of
|
||||
/// destination span is overwritten.
|
||||
///\param src Source
|
||||
///\param dst Destination
|
||||
///\return true, if copy was successful (including empty source span, or
|
||||
/// spans pointing to the same address)
|
||||
///\return false, if the destination span is shorter than the source span.
|
||||
//*************************************************************************
|
||||
template <typename T1, size_t N1, typename T2, size_t N2>
|
||||
typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value &&
|
||||
!etl::is_const<T2>::value, bool>::type
|
||||
copy(const etl::span<T1, N1>& src, const etl::span<T2, N2>& dst)
|
||||
{
|
||||
if (src.empty() || (src.begin() == dst.begin()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (src.size() > dst.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
(void) etl::copy(src.begin(), src.end(), dst.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Template deduction guides.
|
||||
//*************************************************************************
|
||||
@ -818,4 +1103,4 @@ namespace etl
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -283,13 +283,15 @@ namespace etl
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
template <typename ... Args>
|
||||
void emplace(Args && ... args)
|
||||
reference emplace(Args && ... args)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T(etl::forward<Args>(args)...);
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
#else
|
||||
//*************************************************************************
|
||||
@ -297,13 +299,15 @@ namespace etl
|
||||
/// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full.
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
void emplace()
|
||||
reference emplace()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T();
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -312,13 +316,15 @@ namespace etl
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
template <typename T1>
|
||||
void emplace(const T1& value1)
|
||||
reference emplace(const T1& value1)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T(value1);
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -327,13 +333,15 @@ namespace etl
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2>
|
||||
void emplace(const T1& value1, const T2& value2)
|
||||
reference emplace(const T1& value1, const T2& value2)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T(value1, value2);
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -342,13 +350,15 @@ namespace etl
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3>
|
||||
void emplace(const T1& value1, const T2& value2, const T3& value3)
|
||||
reference emplace(const T1& value1, const T2& value2, const T3& value3)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T(value1, value2, value3);
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -357,13 +367,15 @@ namespace etl
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
base_t::add_in();
|
||||
::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ namespace etl
|
||||
{
|
||||
inline namespace string_literals
|
||||
{
|
||||
constexpr etl::string_view operator ""_sv(const char* str, size_t length) noexcept
|
||||
inline constexpr etl::string_view operator ""_sv(const char* str, size_t length) noexcept
|
||||
{
|
||||
return etl::string_view{ str, length };
|
||||
}
|
||||
@ -72,6 +72,7 @@ namespace etl
|
||||
typedef istring interface_type;
|
||||
|
||||
typedef istring::value_type value_type;
|
||||
typedef istring::size_type size_type;
|
||||
|
||||
static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
|
||||
|
||||
@ -243,6 +244,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
string& operator = (const etl::string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
@ -261,7 +272,7 @@ namespace etl
|
||||
};
|
||||
|
||||
template <size_t MAX_SIZE_>
|
||||
ETL_CONSTANT size_t string<MAX_SIZE_>::MAX_SIZE;
|
||||
ETL_CONSTANT typename string<MAX_SIZE_>::size_type string<MAX_SIZE_>::MAX_SIZE;
|
||||
|
||||
//***************************************************************************
|
||||
/// A string implementation that uses a fixed size external buffer.
|
||||
@ -361,6 +372,16 @@ namespace etl
|
||||
this->resize(count, c);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// From string_view.
|
||||
///\param view The string_view.
|
||||
//*************************************************************************
|
||||
explicit string_ext(const etl::string_view& view, value_type* buffer, size_type buffer_size)
|
||||
: istring(buffer, buffer_size - 1U)
|
||||
{
|
||||
this->assign(view.begin(), view.end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor, from an iterator range.
|
||||
///\tparam TIterator The iterator type.
|
||||
@ -385,16 +406,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// From string_view.
|
||||
///\param view The string_view.
|
||||
//*************************************************************************
|
||||
explicit string_ext(const etl::string_view& view, value_type* buffer, size_type buffer_size)
|
||||
: istring(buffer, buffer_size - 1U)
|
||||
{
|
||||
this->assign(view.begin(), view.end());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -408,7 +419,6 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -432,6 +442,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
string_ext& operator = (const etl::string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
|
||||
@ -43,6 +43,14 @@ SOFTWARE.
|
||||
#include "algorithm.h"
|
||||
#include "private/minmax_push.h"
|
||||
|
||||
#if ETL_USING_STL && ETL_USING_CPP17
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
#if ETL_USING_STL
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace etl
|
||||
@ -96,9 +104,9 @@ namespace etl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef TTraits traits_type;
|
||||
typedef size_t size_type;
|
||||
typedef T value_type;
|
||||
typedef TTraits traits_type;
|
||||
typedef size_t size_type;
|
||||
typedef const T& const_reference;
|
||||
typedef const T* const_pointer;
|
||||
typedef const T* const_iterator;
|
||||
@ -366,7 +374,7 @@ namespace etl
|
||||
//*************************************************************************
|
||||
ETL_CONSTEXPR14 basic_string_view substr(size_type position = 0, size_type count = npos) const
|
||||
{
|
||||
basic_string_view view;
|
||||
basic_string_view view = basic_string_view();
|
||||
|
||||
if (position < size())
|
||||
{
|
||||
@ -408,20 +416,48 @@ namespace etl
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 int compare(size_type position1, size_type count1,
|
||||
basic_string_view view,
|
||||
size_type position2, size_type count2) const
|
||||
basic_string_view view,
|
||||
size_type position2, size_type count2) const
|
||||
{
|
||||
return substr(position1, count1).compare(view.substr(position2, count2));
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 int compare(const T* text) const
|
||||
{
|
||||
return compare(etl::basic_string_view<T, TTraits>(text));
|
||||
const T* view_itr = mbegin;
|
||||
const T* text_itr = text;
|
||||
|
||||
while (view_itr != mend && *text_itr != T(0))
|
||||
{
|
||||
if (*view_itr < *text_itr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (*view_itr > *text_itr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
++view_itr;
|
||||
++text_itr;
|
||||
}
|
||||
|
||||
if ((view_itr == mend) && (*text_itr == T(0)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (view_itr == mend)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 int compare(size_type position, size_type count, const T* text) const
|
||||
{
|
||||
return substr(position, count).compare(etl::basic_string_view<T, TTraits>(text));
|
||||
return substr(position, count).compare(text);
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 int compare(size_type position, size_type count1, const T* text, size_type count2) const
|
||||
@ -435,7 +471,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14 bool starts_with(etl::basic_string_view<T, TTraits> view) const
|
||||
{
|
||||
return (size() >= view.size()) &&
|
||||
(compare(0, view.size(), view) == 0);
|
||||
(compare(0, view.size(), view) == 0);
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 bool starts_with(T c) const
|
||||
@ -448,7 +484,7 @@ namespace etl
|
||||
size_t lengthtext = TTraits::length(text);
|
||||
|
||||
return (size() >= lengthtext) &&
|
||||
(compare(0, lengthtext, text) == 0);
|
||||
(compare(0, lengthtext, text) == 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -457,7 +493,7 @@ namespace etl
|
||||
ETL_CONSTEXPR14 bool ends_with(etl::basic_string_view<T, TTraits> view) const
|
||||
{
|
||||
return (size() >= view.size()) &&
|
||||
(compare(size() - view.size(), npos, view) == 0);
|
||||
(compare(size() - view.size(), npos, view) == 0);
|
||||
}
|
||||
|
||||
ETL_CONSTEXPR14 bool ends_with(T c) const
|
||||
@ -471,7 +507,7 @@ namespace etl
|
||||
size_t lengthview = size();
|
||||
|
||||
return (lengthview >= lengthtext) &&
|
||||
(compare(lengthview - lengthtext, lengthtext, text) == 0);
|
||||
(compare(lengthview - lengthtext, lengthtext, text) == 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -747,6 +783,30 @@ namespace etl
|
||||
return find_last_not_of(etl::basic_string_view<T, TTraits>(text), position);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Checks that the view is within this string
|
||||
//*********************************************************************
|
||||
bool contains(const etl::basic_string_view<T, TTraits>& view) const
|
||||
{
|
||||
return find(view) != npos;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Checks that text is within this string
|
||||
//*********************************************************************
|
||||
bool contains(const_pointer s) const
|
||||
{
|
||||
return find(s) != npos;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Checks that character is within this string
|
||||
//*********************************************************************
|
||||
bool contains(value_type c) const
|
||||
{
|
||||
return find(c) != npos;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Equality for string_view.
|
||||
//*************************************************************************
|
||||
@ -916,6 +976,19 @@ void swap(etl::basic_string_view<T, etl::char_traits<T> >& lhs, etl::basic_strin
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Operator overload to write to std basic_ostream
|
||||
//*************************************************************************
|
||||
#if ETL_USING_STL
|
||||
template <typename T>
|
||||
std::basic_ostream<T, std::char_traits<T> > &operator<<(std::basic_ostream<T, std::char_traits<T> > &os,
|
||||
etl::basic_string_view<T, etl::char_traits<T> > text)
|
||||
{
|
||||
os.write(text.data(), text.size());
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "private/minmax_pop.h"
|
||||
|
||||
#endif
|
||||
|
||||
1259
include/etl/tuple.h
Normal file
1259
include/etl/tuple.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -58,10 +58,9 @@ namespace etl
|
||||
typedef TIdType id_type;
|
||||
|
||||
//*********************************************************************
|
||||
ETL_CONSTEXPR type_def()
|
||||
: value(TValue())
|
||||
{
|
||||
}
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR type_def() = default;
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
ETL_CONSTEXPR type_def(TValue value_)
|
||||
@ -70,10 +69,9 @@ namespace etl
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
ETL_CONSTEXPR type_def(const type_def& other)
|
||||
: value(other.value)
|
||||
{
|
||||
}
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR type_def(const type_def& other) = default;
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
ETL_CONSTEXPR operator TValue() const
|
||||
@ -245,11 +243,9 @@ namespace etl
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
ETL_CONSTEXPR14 type_def& operator =(const type_def& rhs)
|
||||
{
|
||||
value = rhs.value;
|
||||
return *this;
|
||||
}
|
||||
#if ETL_USING_CPP11
|
||||
ETL_CONSTEXPR14 type_def& operator =(const type_def& rhs) = default;
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
TValue& get()
|
||||
|
||||
293
include/etl/type_list.h
Normal file
293
include/etl/type_list.h
Normal file
@ -0,0 +1,293 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2025 John Wellbelove
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_TYPE_LIST_INCLUDED
|
||||
#define ETL_TYPE_LIST_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "index_of_type.h"
|
||||
#include "integral_limits.h"
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
#include "utility.h"
|
||||
#include "largest.h"
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Defines a no-position constant.
|
||||
//***************************************************************************
|
||||
static ETL_CONSTANT size_t type_list_npos = etl::integral_limits<size_t>::max;
|
||||
|
||||
//***************************************************************************
|
||||
/// Type list forward declaration.
|
||||
//***************************************************************************
|
||||
template <typename... TTypes>
|
||||
struct type_list;
|
||||
|
||||
//***************************************************************************
|
||||
/// The empty type list.
|
||||
//***************************************************************************
|
||||
template <>
|
||||
struct type_list<>
|
||||
{
|
||||
static constexpr size_t size = 0U;
|
||||
|
||||
using index_sequence_type = etl::make_index_sequence<0>; ///< The index_sequence type for this type_list.
|
||||
|
||||
private:
|
||||
|
||||
type_list() ETL_DELETE;
|
||||
type_list(const type_list&) ETL_DELETE;
|
||||
type_list& operator =(const type_list&) ETL_DELETE;
|
||||
};
|
||||
|
||||
namespace private_type_list
|
||||
{
|
||||
// helper to solve the issue that recursed-rest can't be put directly in type_list::tail definition
|
||||
template <typename... TTypes>
|
||||
struct recursion_helper
|
||||
{
|
||||
using type = type_list<TTypes...>;
|
||||
};
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Recursive type list implementation for multiple types.
|
||||
//***************************************************************************
|
||||
template <typename THead, typename... TTail>
|
||||
struct type_list<THead, TTail...> : type_list<TTail...>
|
||||
{
|
||||
using head = THead;
|
||||
using tail = typename private_type_list::recursion_helper<TTail...>::type;
|
||||
|
||||
static constexpr size_t size = sizeof...(TTail) + 1U;
|
||||
|
||||
using index_sequence_type = etl::make_index_sequence<sizeof...(TTail) + 1U>; ///< The index_sequence type for this type_list.
|
||||
|
||||
private:
|
||||
|
||||
type_list() ETL_DELETE;
|
||||
type_list(const type_list&) ETL_DELETE;
|
||||
type_list& operator =(const type_list&) ETL_DELETE;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Type list implementation for one type.
|
||||
//***************************************************************************
|
||||
template <typename THead>
|
||||
struct type_list<THead> : type_list<>
|
||||
{
|
||||
using head = THead;
|
||||
using tail = typename private_type_list::recursion_helper<>::type;
|
||||
|
||||
static constexpr size_t size = 1U;
|
||||
|
||||
using index_sequence_type = etl::make_index_sequence<1>; ///< The index_sequence type for this type_list.
|
||||
|
||||
private:
|
||||
|
||||
type_list() ETL_DELETE;
|
||||
type_list(const type_list&) ETL_DELETE;
|
||||
type_list& operator =(const type_list&) ETL_DELETE;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Type list size.
|
||||
//***************************************************************************
|
||||
template <typename TTypes>
|
||||
struct type_list_size;
|
||||
|
||||
template <typename... TTypes>
|
||||
struct type_list_size<etl::type_list<TTypes...>> : public etl::integral_constant<size_t, sizeof...(TTypes)>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... TTypes>
|
||||
inline constexpr size_t type_list_size_v = type_list_size<etl::type_list<TTypes...>>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines type as the type found at Index in the type_list.
|
||||
/// Static asserts if Index is out of range.
|
||||
//***************************************************************************
|
||||
template <typename TTypeList, size_t Index>
|
||||
struct type_list_type_at_index
|
||||
{
|
||||
ETL_STATIC_ASSERT(Index < type_list_size<TTypeList>::value, "etl::type_list_type_at_index out of range");
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
|
||||
|
||||
using type = typename type_list_type_at_index<typename TTypeList::tail, Index - 1>::type;
|
||||
};
|
||||
|
||||
template <typename TTypeList>
|
||||
struct type_list_type_at_index<TTypeList, 0>
|
||||
{
|
||||
using type = typename TTypeList::head;
|
||||
};
|
||||
|
||||
template <typename TTypeList, size_t Index>
|
||||
using type_list_type_at_index_t = typename type_list_type_at_index<TTypeList, Index>::type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines an integral constant that is the index of the specified type in the type_list.
|
||||
/// If the type is not in the type_list, then defined as etl::type_list_npos.
|
||||
//***************************************************************************
|
||||
template <typename TTypeList, typename T>
|
||||
struct type_list_index_of_type
|
||||
: public etl::integral_constant<size_t, etl::is_same<typename TTypeList::head, T>::value ? 0 :
|
||||
(type_list_index_of_type<typename TTypeList::tail, T>::value == etl::type_list_npos ? etl::type_list_npos :
|
||||
type_list_index_of_type<typename TTypeList::tail, T>::value + 1)>
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_list_index_of_type<type_list<>, T>
|
||||
: public etl::integral_constant<size_t, etl::type_list_npos>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename TTypeList, typename T>
|
||||
inline constexpr size_t type_list_index_of_v = etl::type_list_index_of_type<TTypeList, T>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines a bool constant that is true if the type_list contains the specified type, otherwise false.
|
||||
//***************************************************************************
|
||||
template <typename T, typename TTypes>
|
||||
struct type_list_contains;
|
||||
|
||||
template <typename T, typename... TTypes>
|
||||
struct type_list_contains<etl::type_list<TTypes...>, T>
|
||||
: public etl::integral_constant<bool, etl::is_one_of<T, TTypes...>::value>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_list_contains<type_list<>, T>
|
||||
: public etl::integral_constant<bool, false>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename TTypeList, typename T>
|
||||
inline constexpr bool type_list_contains_v = etl::type_list_contains<TTypeList, T>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines an integral constant that is maximum sizeof all types in the type_list.
|
||||
/// If the type_list is empty, then defined as 0.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct type_list_max_size;
|
||||
|
||||
template <typename... TTypes>
|
||||
struct type_list_max_size<etl::type_list<TTypes...>>
|
||||
: public etl::integral_constant<size_t, etl::largest<TTypes...>::size>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_list_max_size<type_list<>>
|
||||
: public etl::integral_constant<size_t, 0>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename TTypeList>
|
||||
inline constexpr size_t type_list_max_size_v = etl::type_list_max_size<TTypeList>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Defines an integral constant that is maximum alignment all types in the type_list.
|
||||
/// If the type_list is empty, then defined as 1.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct type_list_max_alignment;
|
||||
|
||||
template <typename... TTypes>
|
||||
struct type_list_max_alignment<etl::type_list<TTypes...>>
|
||||
: public etl::integral_constant<size_t, etl::largest<TTypes...>::alignment>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_list_max_alignment<type_list<>>
|
||||
: public etl::integral_constant<size_t, 1>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename TTypeList>
|
||||
inline constexpr size_t type_list_max_alignment_v = etl::type_list_max_alignment<TTypeList>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Declares a new type_list by selecting types from a given type_list, according to an index sequence.
|
||||
//***************************************************************************
|
||||
template <typename TTypeList, size_t... Indices>
|
||||
struct type_list_select
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_base_of<etl::type_list<>, TTypeList>::value), "TTypeList must be an etl::type_list");
|
||||
|
||||
using type = type_list<type_list_type_at_index_t<TTypeList, Indices>...>;
|
||||
};
|
||||
|
||||
template <typename TTypeList, size_t... Indices>
|
||||
using type_list_select_t = typename type_list_select<TTypeList, Indices...>::type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Concatenates two or more type_lists.
|
||||
//***************************************************************************
|
||||
template <typename... TTypes>
|
||||
struct type_list_cat;
|
||||
|
||||
template <typename... TTypes1, typename... TTypes2, typename... TTail>
|
||||
struct type_list_cat<etl::type_list<TTypes1...>, etl::type_list<TTypes2...>, TTail...>
|
||||
{
|
||||
using type = typename type_list_cat<etl::type_list<TTypes1..., TTypes2...>, TTail...>::type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct type_list_cat<T>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename... TypeLists>
|
||||
using type_list_cat_t = typename type_list_cat<TypeLists...>::type;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -628,17 +628,12 @@ namespace etl
|
||||
{
|
||||
private:
|
||||
|
||||
template<typename T> struct dummy {};
|
||||
struct internal: TDerived, dummy<int>{};
|
||||
|
||||
static TBase* check(TBase*) { return (TBase*)0; }
|
||||
|
||||
template<typename T>
|
||||
static char check(dummy<T>*) { return 0; }
|
||||
static char check(...) { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*));
|
||||
static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*));
|
||||
};
|
||||
|
||||
// For when TBase or TDerived is a fundamental type.
|
||||
@ -1327,6 +1322,79 @@ typedef integral_constant<bool, true> true_type;
|
||||
// ETL extended type traits.
|
||||
//***************************************************************************
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// conjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct conjunction : public etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct conjunction<T> : public T
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool conjunction_v = conjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct disjunction : public etl::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1> struct disjunction<T1> : public T1
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// exclusive_disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename... TTypes>
|
||||
struct exclusive_disjunction;
|
||||
|
||||
template <typename T>
|
||||
struct exclusive_disjunction<T> : public etl::bool_constant<T::value>
|
||||
{
|
||||
};
|
||||
|
||||
// Recursive case: XOR the first two values and recurse
|
||||
template <typename T1, typename T2, typename... TRest>
|
||||
struct exclusive_disjunction<T1, T2, TRest...> : public etl::exclusive_disjunction<etl::integral_constant<bool, etl::disjunction<T1, T2>::value && !etl::conjunction<T1, T2>::value>, TRest...>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// conditional_integral_constant
|
||||
// /\ingroup type_traits
|
||||
@ -1349,19 +1417,11 @@ typedef integral_constant<bool, true> true_type;
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is one of a specified list.
|
||||
/// Template to determine if a type is a base of all types in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_one_of
|
||||
template <typename T, typename... TRest>
|
||||
struct is_one_of : etl::disjunction<etl::is_same<T, TRest>...>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value ||
|
||||
etl::is_one_of<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_one_of<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value;
|
||||
};
|
||||
#else
|
||||
//***************************************************************************
|
||||
@ -1399,21 +1459,46 @@ typedef integral_constant<bool, true> true_type;
|
||||
inline constexpr bool is_one_of_v = etl::is_one_of<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
namespace private_type_traits
|
||||
{
|
||||
//***************************************************************************
|
||||
// Helper to count occurrences of a type in a list of types
|
||||
template<typename T, typename... TTypes>
|
||||
struct count_type;
|
||||
|
||||
// Base case: zero occurrences
|
||||
template<typename T>
|
||||
struct count_type<T> : etl::integral_constant<size_t, 0>
|
||||
{
|
||||
};
|
||||
|
||||
// Recursive case: increment count if head is the same as T, otherwise continue with tail
|
||||
template<typename T, typename THead, typename... TTail>
|
||||
struct count_type<T, THead, TTail...> : etl::integral_constant<size_t, (etl::is_same<T, THead>::value ? 1 : 0) + count_type<T, TTail...>::value>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T, typename... TTypes>
|
||||
struct has_duplicates_of
|
||||
: etl::integral_constant<bool, (private_type_traits::count_type<T, TTypes...>::value > 1)>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename... TRest>
|
||||
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is a base of all types in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_base_of_all
|
||||
template <typename TBase, typename... TDerived>
|
||||
struct is_base_of_all : etl::conjunction<etl::is_base_of<TBase, TDerived>...>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value &&
|
||||
etl::is_base_of_all<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_base_of_all<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -1426,18 +1511,11 @@ typedef integral_constant<bool, true> true_type;
|
||||
//***************************************************************************
|
||||
/// Template to determine if a type is a base of any type in a specified list.
|
||||
///\ingroup types
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct is_base_of_any
|
||||
template <typename TBase, typename... TDerived>
|
||||
struct is_base_of_any : etl::disjunction<etl::is_base_of<TBase, TDerived>...>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value ||
|
||||
etl::is_base_of_any<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct is_base_of_any<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_base_of<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
@ -1445,6 +1523,28 @@ typedef integral_constant<bool, true> true_type;
|
||||
inline constexpr bool is_base_of_any_v = etl::is_base_of_any<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Get the Nth base of a recursively inherited type.
|
||||
/// Requires that the class has defined 'base_type'.
|
||||
//***************************************************************************
|
||||
// Recursive definition of the type.
|
||||
template <size_t N, typename TType>
|
||||
struct nth_base
|
||||
{
|
||||
typedef typename nth_base<N - 1U, typename TType::base_type>::type type;
|
||||
};
|
||||
|
||||
template <typename TType>
|
||||
struct nth_base<0, TType>
|
||||
{
|
||||
typedef TType type;
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <size_t N, typename TType>
|
||||
using nth_base_t = typename nth_base<N, TType>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// A set of templates to allow related types to be derived.
|
||||
///\ingroup types
|
||||
@ -1598,70 +1698,15 @@ typedef integral_constant<bool, true> true_type;
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// are_all_same
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
struct are_all_same
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value &&
|
||||
etl::are_all_same<T, TRest...>::value;
|
||||
};
|
||||
|
||||
template <typename T, typename T1>
|
||||
struct are_all_same<T, T1>
|
||||
{
|
||||
static const bool value = etl::is_same<T, T1>::value;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename T1, typename... TRest>
|
||||
inline constexpr bool are_all_same_v = are_all_same<T, T1, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// conjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct conjunction : public etl::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct conjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), etl::conjunction<Tn...>, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct conjunction<T> : public T
|
||||
template <typename T, typename... TRest>
|
||||
struct are_all_same : etl::conjunction<etl::is_same<T, TRest>...>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool conjunction_v = conjunction<T...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// disjunction
|
||||
#if ETL_USING_CPP11
|
||||
template <typename...>
|
||||
struct disjunction : public etl::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1, typename... Tn>
|
||||
struct disjunction<T1, Tn...> : public etl::conditional_t<bool(T1::value), T1, disjunction<Tn...>>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T1> struct disjunction<T1> : public T1
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename... T>
|
||||
inline constexpr bool disjunction_v = etl::disjunction<T...>::value;
|
||||
template <typename T, typename... TRest>
|
||||
inline constexpr bool are_all_same_v = are_all_same<T, TRest...>::value;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
@ -2342,18 +2387,6 @@ typedef integral_constant<bool, true> true_type;
|
||||
template <typename T, typename... TTypes>
|
||||
inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************
|
||||
// has_duplicates_of
|
||||
template <typename T, typename... TTypes>
|
||||
struct has_duplicates_of : etl::bool_constant<(etl::count_of<T, TTypes...>::value > 1U)> {};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
template <typename T, typename... TTypes>
|
||||
inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of<T, TTypes...>::value;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper macros
|
||||
|
||||
@ -46,7 +46,7 @@ namespace etl
|
||||
{
|
||||
inline namespace string_literals
|
||||
{
|
||||
constexpr etl::u16string_view operator ""_sv(const char16_t* str, size_t length) noexcept
|
||||
inline constexpr etl::u16string_view operator ""_sv(const char16_t* str, size_t length) noexcept
|
||||
{
|
||||
return etl::u16string_view{ str, length };
|
||||
}
|
||||
@ -227,6 +227,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u16string& operator = (const etl::u16string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
@ -366,8 +376,8 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// From u16string_view.
|
||||
///\param view The u16string_view.
|
||||
/// From string_view.
|
||||
///\param view The string_view.
|
||||
//*************************************************************************
|
||||
explicit u16string_ext(const etl::u16string_view& view, value_type* buffer, size_type buffer_size)
|
||||
: iu16string(buffer, buffer_size - 1U)
|
||||
@ -388,7 +398,6 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -412,6 +421,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u16string_ext& operator = (const etl::u16string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
|
||||
@ -46,7 +46,7 @@ namespace etl
|
||||
{
|
||||
inline namespace string_literals
|
||||
{
|
||||
constexpr etl::u32string_view operator ""_sv(const char32_t* str, size_t length) noexcept
|
||||
inline constexpr etl::u32string_view operator ""_sv(const char32_t* str, size_t length) noexcept
|
||||
{
|
||||
return etl::u32string_view{ str, length };
|
||||
}
|
||||
@ -227,6 +227,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u32string& operator = (const etl::u32string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
@ -366,8 +376,8 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// From u32string_view.
|
||||
///\param view The u32string_view.
|
||||
/// From string_view.
|
||||
///\param view The string_view.
|
||||
//*************************************************************************
|
||||
explicit u32string_ext(const etl::u32string_view& view, value_type* buffer, size_type buffer_size)
|
||||
: iu32string(buffer, buffer_size - 1U)
|
||||
@ -388,7 +398,6 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -412,6 +421,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u32string_ext& operator = (const etl::u32string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
|
||||
@ -49,7 +49,7 @@ namespace etl
|
||||
{
|
||||
inline namespace string_literals
|
||||
{
|
||||
constexpr etl::u8string_view operator ""_sv(const char8_t* str, size_t length) noexcept
|
||||
inline constexpr etl::u8string_view operator ""_sv(const char8_t* str, size_t length) noexcept
|
||||
{
|
||||
return etl::u8string_view{ str, length };
|
||||
}
|
||||
@ -244,6 +244,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u8string& operator = (const etl::u8string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
@ -409,7 +419,6 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -433,6 +442,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
u8string_ext& operator = (const etl::u8string_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
59
include/etl/uncopyable.h
Normal file
59
include/etl/uncopyable.h
Normal file
@ -0,0 +1,59 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2024 BMW AG
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_UNCOPYABLE_INCLUDED
|
||||
#define ETL_UNCOPYABLE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
/// An uncopyable base class.
|
||||
/// Can be used to make a class uncopyable by deriving from it.
|
||||
//***************************************************************************
|
||||
class uncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
uncopyable(uncopyable const&) = delete;
|
||||
uncopyable& operator=(uncopyable const&) = delete;
|
||||
|
||||
protected:
|
||||
|
||||
uncopyable() = default;
|
||||
~uncopyable() = default;
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -52,6 +52,8 @@ SOFTWARE.
|
||||
#include "placement_new.h"
|
||||
#include "initializer_list.h"
|
||||
|
||||
#include "private/comparator_is_transparent.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//*****************************************************************************
|
||||
@ -599,6 +601,18 @@ namespace etl
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the bucket index for the key.
|
||||
///\return The bucket index for the key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type get_bucket_index(const K& key) const
|
||||
{
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
@ -610,6 +624,20 @@ namespace etl
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type bucket_size(const K& key) const
|
||||
{
|
||||
size_t index = bucket(key);
|
||||
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the maximum number of the buckets the container can hold.
|
||||
///\return The maximum number of the buckets the container can hold.
|
||||
@ -716,6 +744,52 @@ namespace etl
|
||||
return pbucket->begin()->key_value_pair.second;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'key'
|
||||
///\param key The key.
|
||||
///\return A reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
mapped_reference operator [](const K& key)
|
||||
{
|
||||
// Find the bucket.
|
||||
bucket_t* pbucket = pbuckets + get_bucket_index(key);
|
||||
|
||||
// Find the first node in the bucket.
|
||||
local_iterator inode = pbucket->begin();
|
||||
|
||||
// Walk the list looking for the right one.
|
||||
while (inode != pbucket->end())
|
||||
{
|
||||
// Equal keys?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
// Found a match.
|
||||
return inode->key_value_pair.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't exist, so add a new one.
|
||||
// Get a new node.
|
||||
node_t* node = allocate_data_node();
|
||||
node->clear();
|
||||
::new ((void*)etl::addressof(node->key_value_pair.first)) key_type(key);
|
||||
::new ((void*)etl::addressof(node->key_value_pair.second)) mapped_type();
|
||||
ETL_INCREMENT_DEBUG_COUNT;
|
||||
|
||||
pbucket->insert_after(pbucket->before_begin(), *node);
|
||||
|
||||
adjust_first_last_markers_after_insert(pbucket);
|
||||
|
||||
return pbucket->begin()->key_value_pair.second;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'key'
|
||||
/// If asserts or exceptions are enabled, emits an etl::unordered_map_out_of_range if the key is not in the range.
|
||||
@ -786,6 +860,82 @@ namespace etl
|
||||
return begin()->second;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'key'
|
||||
/// If asserts or exceptions are enabled, emits an etl::unordered_map_out_of_range if the key is not in the range.
|
||||
///\param key The key.
|
||||
///\return A reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
mapped_reference at(const K& key)
|
||||
{
|
||||
// Find the bucket.
|
||||
bucket_t* pbucket = pbuckets + get_bucket_index(key);
|
||||
|
||||
// Find the first node in the bucket.
|
||||
local_iterator inode = pbucket->begin();
|
||||
|
||||
// Walk the list looking for the right one.
|
||||
while (inode != pbucket->end())
|
||||
{
|
||||
// Equal keys?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
// Found a match.
|
||||
return inode->key_value_pair.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't exist.
|
||||
ETL_ASSERT(false, ETL_ERROR(unordered_map_out_of_range));
|
||||
|
||||
return begin()->second;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the value at index 'key'
|
||||
/// If asserts or exceptions are enabled, emits an etl::unordered_map_out_of_range if the key is not in the range.
|
||||
///\param key The key.
|
||||
///\return A const reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
const_mapped_reference at(const K& key) const
|
||||
{
|
||||
// Find the bucket.
|
||||
bucket_t* pbucket = pbuckets + get_bucket_index(key);
|
||||
|
||||
// Find the first node in the bucket.
|
||||
local_iterator inode = pbucket->begin();
|
||||
|
||||
// Walk the list looking for the right one.
|
||||
while (inode != pbucket->end())
|
||||
{
|
||||
// Equal keys?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
// Found a match.
|
||||
return inode->key_value_pair.second;
|
||||
}
|
||||
else
|
||||
{
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't exist.
|
||||
ETL_ASSERT(false, ETL_ERROR(unordered_map_out_of_range));
|
||||
|
||||
return begin()->second;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Assigns values to the unordered_map.
|
||||
/// If asserts or exceptions are enabled, emits unordered_map_full if the unordered_map does not have enough free space.
|
||||
@ -1040,6 +1190,41 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param key The key to erase.
|
||||
///\return The number of elements erased. 0 or 1.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t erase(const K& key)
|
||||
{
|
||||
size_t n = 0UL;
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t& bucket = pbuckets[index];
|
||||
|
||||
local_iterator iprevious = bucket.before_begin();
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
// Search for the key, if we have it.
|
||||
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key_value_pair.first, key)))
|
||||
{
|
||||
++iprevious;
|
||||
++icurrent;
|
||||
}
|
||||
|
||||
// Did we find it?
|
||||
if (icurrent != bucket.end())
|
||||
{
|
||||
delete_data_node(iprevious, icurrent, bucket);
|
||||
n = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param ielement Iterator to the element.
|
||||
@ -1141,6 +1326,19 @@ namespace etl
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Counts an element.
|
||||
///\param key The key to search for.
|
||||
///\return 1 if the key exists, otherwise 0.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t count(const K& key) const
|
||||
{
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
@ -1209,6 +1407,80 @@ namespace etl
|
||||
return end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
return iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
return iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
@ -1251,6 +1523,54 @@ namespace etl
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator f = find(key);
|
||||
iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<iterator, iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return A const iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the unordered_map.
|
||||
//*************************************************************************
|
||||
@ -1361,6 +1681,25 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_map contains the key.
|
||||
//*************************************************************************
|
||||
bool contains(const_key_reference key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_map contains the key.
|
||||
//*************************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
bool contains(const K& key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
@ -52,6 +52,8 @@ SOFTWARE.
|
||||
#include "placement_new.h"
|
||||
#include "initializer_list.h"
|
||||
|
||||
#include "private/comparator_is_transparent.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//*****************************************************************************
|
||||
@ -597,6 +599,18 @@ namespace etl
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the bucket index for the key.
|
||||
///\return The bucket index for the key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type get_bucket_index(const K& key) const
|
||||
{
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
@ -608,6 +622,20 @@ namespace etl
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type bucket_size(const K& key) const
|
||||
{
|
||||
size_t index = bucket(key);
|
||||
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the maximum number of the buckets the container can hold.
|
||||
///\return The maximum number of the buckets the container can hold.
|
||||
@ -868,6 +896,43 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param key The key to erase.
|
||||
///\return The number of elements erased.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t erase(const K& key)
|
||||
{
|
||||
size_t n = 0UL;
|
||||
size_t bucket_id = get_bucket_index(key);
|
||||
|
||||
bucket_t& bucket = pbuckets[bucket_id];
|
||||
|
||||
local_iterator iprevious = bucket.before_begin();
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
while (icurrent != bucket.end())
|
||||
{
|
||||
if (key_equal_function(icurrent->key_value_pair.first, key))
|
||||
{
|
||||
delete_data_node(iprevious, icurrent, bucket);
|
||||
++n;
|
||||
icurrent = iprevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iprevious;
|
||||
}
|
||||
|
||||
++icurrent;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param ielement Iterator to the element.
|
||||
@ -985,6 +1050,35 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Counts an element.
|
||||
///\param key The key to search for.
|
||||
///\return 1 if the key exists, otherwise 0.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t count(const K& key) const
|
||||
{
|
||||
size_t n = 0UL;
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
@ -1053,6 +1147,80 @@ namespace etl
|
||||
return end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
return iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key_value_pair.first))
|
||||
{
|
||||
return const_iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
@ -1105,6 +1273,64 @@ namespace etl
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator f = find(key);
|
||||
iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<iterator, iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return A const iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, l->first))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the unordered_multimap.
|
||||
//*************************************************************************
|
||||
@ -1216,6 +1442,25 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_multimap contains the key.
|
||||
//*************************************************************************
|
||||
bool contains(const_key_reference key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_map contains the key.
|
||||
//*************************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
bool contains(const K& key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
@ -51,6 +51,8 @@ SOFTWARE.
|
||||
#include "placement_new.h"
|
||||
#include "initializer_list.h"
|
||||
|
||||
#include "private/comparator_is_transparent.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//*****************************************************************************
|
||||
@ -588,6 +590,18 @@ namespace etl
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the bucket index for the key.
|
||||
///\return The bucket index for the key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type get_bucket_index(const K& key) const
|
||||
{
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
@ -599,6 +613,20 @@ namespace etl
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type bucket_size(const K& key) const
|
||||
{
|
||||
size_t index = bucket(key);
|
||||
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the maximum number of the buckets the container can hold.
|
||||
///\return The maximum number of the buckets the container can hold.
|
||||
@ -712,6 +740,79 @@ namespace etl
|
||||
return result;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the unordered_multiset.
|
||||
/// If asserts or exceptions are enabled, emits unordered_multiset_full if the unordered_multiset is already full.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, bool> insert(const K& key)
|
||||
{
|
||||
ETL_OR_STD::pair<iterator, bool> result(end(), false);
|
||||
|
||||
ETL_ASSERT(!full(), ETL_ERROR(unordered_multiset_full));
|
||||
|
||||
// Get the hash index.
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
// Get the bucket & bucket iterator.
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// The first one in the bucket?
|
||||
if (bucket.empty())
|
||||
{
|
||||
// Get a new node.
|
||||
node_t* node = allocate_data_node();
|
||||
node->clear();
|
||||
::new (&node->key) value_type(key);
|
||||
ETL_INCREMENT_DEBUG_COUNT;
|
||||
|
||||
// Just add the pointer to the bucket;
|
||||
bucket.insert_after(bucket.before_begin(), *node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
|
||||
result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
|
||||
result.second = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step though the bucket looking for a place to insert.
|
||||
local_iterator inode_previous = bucket.before_begin();
|
||||
local_iterator inode = bucket.begin();
|
||||
|
||||
while (inode != bucket.end())
|
||||
{
|
||||
// Do we already have this key?
|
||||
if (key_equal_function(inode->key, key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++inode_previous;
|
||||
++inode;
|
||||
}
|
||||
|
||||
// Get a new node.
|
||||
node_t* node = allocate_data_node();
|
||||
node->clear();
|
||||
::new (&node->key) value_type(key);
|
||||
ETL_INCREMENT_DEBUG_COUNT;
|
||||
|
||||
// Add the node to the end of the bucket;
|
||||
bucket.insert_after(inode_previous, *node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
++inode_previous;
|
||||
|
||||
result.first = iterator((pbuckets + number_of_buckets), pbucket, inode_previous);
|
||||
result.second = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the unordered_multiset.
|
||||
@ -846,6 +947,43 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param key The key to erase.
|
||||
///\return The number of elements erased. 0 or 1.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t erase(const K& key)
|
||||
{
|
||||
size_t n = 0UL;
|
||||
size_t bucket_id = get_bucket_index(key);
|
||||
|
||||
bucket_t& bucket = pbuckets[bucket_id];
|
||||
|
||||
local_iterator iprevious = bucket.before_begin();
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
while (icurrent != bucket.end())
|
||||
{
|
||||
if (key_equal_function(icurrent->key, key))
|
||||
{
|
||||
delete_data_node(iprevious, icurrent, bucket);
|
||||
++n;
|
||||
icurrent = iprevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iprevious;
|
||||
}
|
||||
|
||||
++icurrent;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param ielement Iterator to the element.
|
||||
@ -963,6 +1101,35 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Counts an element.
|
||||
///\param key The key to search for.
|
||||
///\return 1 if the key exists, otherwise 0.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t count(const K& key) const
|
||||
{
|
||||
size_t n = 0UL;
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
@ -997,6 +1164,43 @@ namespace etl
|
||||
return end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key))
|
||||
{
|
||||
return iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
@ -1031,6 +1235,43 @@ namespace etl
|
||||
return end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key))
|
||||
{
|
||||
return iterator((pbuckets + number_of_buckets), pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
@ -1057,6 +1298,35 @@ namespace etl
|
||||
return ETL_OR_STD::pair<iterator, iterator>(f, l);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator f = find(key);
|
||||
iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<iterator, iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
@ -1083,6 +1353,35 @@ namespace etl
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key key in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return A const iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
|
||||
while ((l != end()) && key_equal_function(key, *l))
|
||||
{
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the unordered_multiset.
|
||||
//*************************************************************************
|
||||
@ -1194,6 +1493,25 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_multiset contains the key.
|
||||
//*************************************************************************
|
||||
bool contains(key_parameter_t key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_map contains the key.
|
||||
//*************************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
bool contains(const K& key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
@ -52,6 +52,8 @@ SOFTWARE.
|
||||
#include "placement_new.h"
|
||||
#include "initializer_list.h"
|
||||
|
||||
#include "private/comparator_is_transparent.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
//*****************************************************************************
|
||||
@ -589,6 +591,18 @@ namespace etl
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the bucket index for the key.
|
||||
///\return The bucket index for the key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type get_bucket_index(const K& key) const
|
||||
{
|
||||
return key_hash_function(key) % number_of_buckets;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
@ -600,6 +614,20 @@ namespace etl
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns the size of the bucket key.
|
||||
///\return The bucket size of the bucket key.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_type bucket_size(const K& key) const
|
||||
{
|
||||
size_t index = bucket(key);
|
||||
|
||||
return etl::distance(pbuckets[index].begin(), pbuckets[index].end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns the maximum number of the buckets the container can hold.
|
||||
///\return The maximum number of the buckets the container can hold.
|
||||
@ -730,6 +758,96 @@ namespace etl
|
||||
return result;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the unordered_set.
|
||||
/// If asserts or exceptions are enabled, emits unordered_set_full if the unordered_set is already full.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, bool> insert(const K& key)
|
||||
{
|
||||
ETL_OR_STD::pair<iterator, bool> result(end(), false);
|
||||
|
||||
if (full())
|
||||
{
|
||||
iterator iter = find(key);
|
||||
if (iter == end())
|
||||
{
|
||||
ETL_ASSERT_FAIL(ETL_ERROR(unordered_set_full));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.first = iter;
|
||||
result.second = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the hash index.
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
// Get the bucket & bucket iterator.
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// The first one in the bucket?
|
||||
if (bucket.empty())
|
||||
{
|
||||
// Get a new node.
|
||||
node_t* node = allocate_data_node();
|
||||
node->clear();
|
||||
::new (&node->key) value_type(key);
|
||||
ETL_INCREMENT_DEBUG_COUNT;
|
||||
|
||||
// Just add the pointer to the bucket;
|
||||
bucket.insert_after(bucket.before_begin(), *node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
|
||||
result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
|
||||
result.second = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step though the bucket looking for a place to insert.
|
||||
local_iterator inode_previous = bucket.before_begin();
|
||||
local_iterator inode = bucket.begin();
|
||||
|
||||
while (inode != bucket.end())
|
||||
{
|
||||
// Do we already have this key?
|
||||
if (key_equal_function(inode->key, key))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++inode_previous;
|
||||
++inode;
|
||||
}
|
||||
|
||||
// Not already there?
|
||||
if (inode == bucket.end())
|
||||
{
|
||||
// Get a new node.
|
||||
node_t* node = allocate_data_node();
|
||||
node->clear();
|
||||
::new (&node->key) value_type(key);
|
||||
ETL_INCREMENT_DEBUG_COUNT;
|
||||
|
||||
// Add the node to the end of the bucket;
|
||||
bucket.insert_after(inode_previous, *node);
|
||||
adjust_first_last_markers_after_insert(&bucket);
|
||||
++inode_previous;
|
||||
|
||||
result.first = iterator(pbuckets + number_of_buckets, pbucket, inode_previous);
|
||||
result.second = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the unordered_set.
|
||||
@ -892,6 +1010,41 @@ namespace etl
|
||||
return n;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param key The key to erase.
|
||||
///\return The number of elements erased. 0 or 1.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t erase(const K& key)
|
||||
{
|
||||
size_t n = 0UL;
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t& bucket = pbuckets[index];
|
||||
|
||||
local_iterator iprevious = bucket.before_begin();
|
||||
local_iterator icurrent = bucket.begin();
|
||||
|
||||
// Search for the key, if we have it.
|
||||
while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key)))
|
||||
{
|
||||
++iprevious;
|
||||
++icurrent;
|
||||
}
|
||||
|
||||
// Did we find it?
|
||||
if (icurrent != bucket.end())
|
||||
{
|
||||
delete_data_node(iprevious, icurrent, bucket);
|
||||
n = 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param ielement Iterator to the element.
|
||||
@ -993,6 +1146,19 @@ namespace etl
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Counts an element.
|
||||
///\param key The key to search for.
|
||||
///\return 1 if the key exists, otherwise 0.
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
size_t count(const K& key) const
|
||||
{
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
@ -1061,6 +1227,80 @@ namespace etl
|
||||
return end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
iterator find(const K& key)
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key))
|
||||
{
|
||||
return iterator(pbuckets + number_of_buckets, pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Finds an element.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator to the element if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
const_iterator find(const K& key) const
|
||||
{
|
||||
size_t index = get_bucket_index(key);
|
||||
|
||||
bucket_t* pbucket = pbuckets + index;
|
||||
bucket_t& bucket = *pbucket;
|
||||
|
||||
// Is the bucket not empty?
|
||||
if (!bucket.empty())
|
||||
{
|
||||
// Step though the list until we find the end or an equivalent key.
|
||||
local_iterator inode = bucket.begin();
|
||||
local_iterator iend = bucket.end();
|
||||
|
||||
while (inode != iend)
|
||||
{
|
||||
// Do we have this one?
|
||||
if (key_equal_function(key, inode->key))
|
||||
{
|
||||
return iterator(pbuckets + number_of_buckets, pbucket, inode);
|
||||
}
|
||||
|
||||
++inode;
|
||||
}
|
||||
}
|
||||
|
||||
return end();
|
||||
}
|
||||
#endif
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key 'key' in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
@ -1103,6 +1343,54 @@ namespace etl
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key 'key' in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return An iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<iterator, iterator> equal_range(const K& key)
|
||||
{
|
||||
iterator f = find(key);
|
||||
iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<iterator, iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*********************************************************************
|
||||
/// Returns a range containing all elements with key 'key' in the container.
|
||||
/// The range is defined by two iterators, the first pointing to the first
|
||||
/// element of the wanted range and the second pointing past the last
|
||||
/// element of the range.
|
||||
///\param key The key to search for.
|
||||
///\return A const iterator pair to the range of elements if the key exists, otherwise end().
|
||||
//*********************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
ETL_OR_STD::pair<const_iterator, const_iterator> equal_range(const K& key) const
|
||||
{
|
||||
const_iterator f = find(key);
|
||||
const_iterator l = f;
|
||||
|
||||
if (l != end())
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
return ETL_OR_STD::pair<const_iterator, const_iterator>(f, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the unordered_set.
|
||||
//*************************************************************************
|
||||
@ -1214,6 +1502,25 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_set contains the key.
|
||||
//*************************************************************************
|
||||
bool contains(key_parameter_t key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// Check if the unordered_map contains the key.
|
||||
//*************************************************************************
|
||||
template <typename K, typename KE = TKeyEqual, etl::enable_if_t<comparator_is_transparent<KE>::value, int> = 0>
|
||||
bool contains(const K& key) const
|
||||
{
|
||||
return find(key) != end();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
@ -34,6 +34,9 @@ SOFTWARE.
|
||||
#include "platform.h"
|
||||
#include "type_traits.h"
|
||||
|
||||
#include "private/tuple_element.h"
|
||||
#include "private/tuple_size.h"
|
||||
|
||||
#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL
|
||||
#if ETL_USING_CPP11
|
||||
#include <utility>
|
||||
@ -325,6 +328,33 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//******************************************************************************
|
||||
template <size_t Index, typename T1, typename T2>
|
||||
struct tuple_element<Index, ETL_OR_STD::pair<T1, T2> >
|
||||
{
|
||||
ETL_STATIC_ASSERT(Index < 2U, "pair has only 2 elements");
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct tuple_element<0U, ETL_OR_STD::pair<T1, T2> >
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct tuple_element<1U, ETL_OR_STD::pair<T1, T2> >
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
//******************************************************************************
|
||||
template <typename T1, typename T2>
|
||||
struct tuple_size<ETL_OR_STD::pair<T1, T2>> : public etl::integral_constant<size_t, 2U>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
//******************************************************************************
|
||||
template <typename T1, typename T2>
|
||||
inline void swap(pair<T1, T2>& a, pair<T1, T2>& b)
|
||||
@ -332,7 +362,7 @@ namespace etl
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
/// Two pairs of the same type are equal iff their members are equal.
|
||||
/// Two pairs of the same type are equal if their members are equal.
|
||||
template <typename T1, typename T2>
|
||||
inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||
{
|
||||
@ -512,13 +542,13 @@ namespace etl
|
||||
template <size_t N, size_t... Indices>
|
||||
struct make_index_sequence<N, etl::integer_sequence<size_t, Indices...>>
|
||||
{
|
||||
typedef typename make_index_sequence<N - 1, etl::integer_sequence<size_t, N - 1, Indices...>>::type type;
|
||||
using type = typename make_index_sequence<N - 1, etl::integer_sequence<size_t, N - 1, Indices...>>::type;
|
||||
};
|
||||
|
||||
template <size_t... Indices>
|
||||
struct make_index_sequence<0, etl::integer_sequence<size_t, Indices...>>
|
||||
{
|
||||
typedef etl::integer_sequence<size_t, Indices...> type;
|
||||
using type = etl::integer_sequence<size_t, Indices...>;
|
||||
};
|
||||
}
|
||||
|
||||
@ -526,9 +556,15 @@ namespace etl
|
||||
template <size_t N>
|
||||
using make_index_sequence = typename private_integer_sequence::make_index_sequence<N, etl::integer_sequence<size_t>>::type;
|
||||
|
||||
template <typename... TTypes>
|
||||
using make_index_sequence_for = typename private_integer_sequence::make_index_sequence<sizeof...(TTypes), etl::integer_sequence<size_t>>::type;
|
||||
|
||||
//***********************************
|
||||
template <size_t... Indices>
|
||||
using index_sequence = etl::integer_sequence<size_t, Indices...>;
|
||||
|
||||
template <typename... TTypes>
|
||||
using index_sequence_for = typename etl::make_index_sequence_for<TTypes...>;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
@ -601,10 +637,13 @@ namespace etl
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*************************************************************************
|
||||
/// A function wrapper for free/global functions.
|
||||
// A function wrapper for free/global functions.
|
||||
// Deprecated.
|
||||
// See etl::function_ptr_as_functor for a runtime time wrapper option.
|
||||
// See etl::function_as_functor for a compile time wrapper option.
|
||||
//*************************************************************************
|
||||
template <typename TReturn, typename... TParams>
|
||||
class functor
|
||||
class ETL_DEPRECATED functor
|
||||
{
|
||||
public:
|
||||
|
||||
@ -629,18 +668,18 @@ namespace etl
|
||||
/// The pointer to the function.
|
||||
TReturn(*ptr)(TParams...);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*****************************************************************************
|
||||
// A wrapper for a member function
|
||||
// Wrap a member function with a static free function.
|
||||
// Creates a static member function that calls the specified member function.
|
||||
// Deprecated
|
||||
// See etl::member_function_as_static
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
class member_function_wrapper;
|
||||
|
||||
template <typename TReturn, typename... TParams>
|
||||
class member_function_wrapper<TReturn(TParams...)>
|
||||
class ETL_DEPRECATED member_function_wrapper<TReturn(TParams...)>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -650,12 +689,12 @@ namespace etl
|
||||
return (Instance.*Method)(etl::forward<TParams>(params)...);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*****************************************************************************
|
||||
// A wrapper for a functor
|
||||
// Wrap a functor with a static free function.
|
||||
// Creates a static member function that calls the specified functor.
|
||||
// Deprecated
|
||||
// See etl::functor_as_static
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
class functor_wrapper;
|
||||
@ -672,6 +711,104 @@ namespace etl
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
//*****************************************************************************
|
||||
// Wraps a functor with a static free function at compile time.
|
||||
// Creates a static member 'call' that calls the specified functor.
|
||||
//*****************************************************************************
|
||||
template <auto& Instance>
|
||||
struct functor_as_static
|
||||
{
|
||||
template <typename... TArgs>
|
||||
static constexpr auto call(TArgs&&... args)
|
||||
{
|
||||
return (Instance.operator())(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Wraps a member function with a static free function at compile time.
|
||||
// Creates a static member 'call' that calls the specified member function.
|
||||
//*****************************************************************************
|
||||
template <auto Method, auto& Instance>
|
||||
struct member_function_as_static
|
||||
{
|
||||
template <typename... TArgs>
|
||||
static constexpr auto call(TArgs&&... args)
|
||||
{
|
||||
return (Instance.*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Wraps a member function with a functor at compile time.
|
||||
// Creates a functor that calls the specified member function.
|
||||
//*****************************************************************************
|
||||
template <auto Method, auto& Instance>
|
||||
class member_function_as_functor
|
||||
{
|
||||
public:
|
||||
|
||||
template <typename... TArgs>
|
||||
constexpr auto operator()(TArgs&&... args) const -> decltype((Instance.*Method)(etl::forward<TArgs>(args)...))
|
||||
{
|
||||
return (Instance.*Method)(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// Wraps a function with a functor at compile time.
|
||||
// Creates a functor that calls the specified free function.
|
||||
//*****************************************************************************
|
||||
template <auto Function>
|
||||
class function_as_functor
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename... TArgs>
|
||||
constexpr auto operator()(TArgs&&... args) const -> decltype(Function(etl::forward<TArgs>(args)...))
|
||||
{
|
||||
return Function(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
//*****************************************************************************
|
||||
// Wraps a function pointer with a functor at run time.
|
||||
// Creates a functor that calls the specified free function.
|
||||
//*****************************************************************************
|
||||
template <typename T>
|
||||
class function_ptr_as_functor;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
class function_ptr_as_functor<TReturn(TArgs...)>
|
||||
{
|
||||
public:
|
||||
|
||||
//*********************************
|
||||
/// Constructor.
|
||||
//*********************************
|
||||
constexpr function_ptr_as_functor(TReturn(*ptr_)(TArgs...))
|
||||
: ptr(ptr_)
|
||||
{
|
||||
}
|
||||
|
||||
//*********************************
|
||||
/// Const function operator.
|
||||
//*********************************
|
||||
constexpr TReturn operator()(TArgs... args) const
|
||||
{
|
||||
return ptr(etl::forward<TArgs>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// The pointer to the function.
|
||||
TReturn(*ptr)(TArgs...);
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -47,7 +47,6 @@ SOFTWARE.
|
||||
#include "functional.h"
|
||||
#include "static_assert.h"
|
||||
#include "placement_new.h"
|
||||
#include "algorithm.h"
|
||||
#include "initializer_list.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@ -39,8 +39,8 @@ SOFTWARE.
|
||||
///\ingroup utilities
|
||||
|
||||
#define ETL_VERSION_MAJOR 20
|
||||
#define ETL_VERSION_MINOR 39
|
||||
#define ETL_VERSION_PATCH 4
|
||||
#define ETL_VERSION_MINOR 40
|
||||
#define ETL_VERSION_PATCH 0
|
||||
|
||||
#define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH)
|
||||
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH)
|
||||
|
||||
@ -46,7 +46,7 @@ namespace etl
|
||||
{
|
||||
inline namespace string_literals
|
||||
{
|
||||
constexpr etl::wstring_view operator ""_sv(const wchar_t* str, size_t length) noexcept
|
||||
inline constexpr etl::wstring_view operator ""_sv(const wchar_t* str, size_t length) noexcept
|
||||
{
|
||||
return etl::wstring_view{ str, length };
|
||||
}
|
||||
@ -227,6 +227,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
wstring& operator = (const etl::wstring_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
@ -366,8 +376,8 @@ namespace etl
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
/// From wstring_view.
|
||||
///\param view The wstring_view.
|
||||
/// From string_view.
|
||||
///\param view The string_view.
|
||||
//*************************************************************************
|
||||
explicit wstring_ext(const etl::wstring_view& view, value_type* buffer, size_type buffer_size)
|
||||
: iwstring(buffer, buffer_size - 1U)
|
||||
@ -388,7 +398,6 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
@ -412,6 +421,16 @@ namespace etl
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
wstring_ext& operator = (const etl::wstring_view& view)
|
||||
{
|
||||
this->assign(view);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Fix the internal pointers after a low level memory copy.
|
||||
//*************************************************************************
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Embedded Template Library",
|
||||
"version": "20.39.4",
|
||||
"version": "20.40.0",
|
||||
"authors": {
|
||||
"name": "John Wellbelove",
|
||||
"email": "john.wellbelove@etlcpp.com"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
name=Embedded Template Library
|
||||
version=20.39.4
|
||||
version=20.40.0
|
||||
author= John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
|
||||
license=MIT
|
||||
|
||||
@ -1,4 +1,68 @@
|
||||
===============================================================================
|
||||
20.40.0
|
||||
|
||||
Updates:
|
||||
Added new C++17 function wrappers
|
||||
Simplified definition of is_base_of
|
||||
Fixed static definition for etl::string
|
||||
Redefined ETL_DEPRECATED
|
||||
Updated nth_type to handle a type list of zero length
|
||||
Updated Github Actions to checkout@v4
|
||||
Added make_delegate for C++17
|
||||
Added starts_with and ends_with to basic_string
|
||||
Made construction from std::basic_string_view explicit
|
||||
Added contains member function to string_view
|
||||
Fixed possible null dereference for etl::multi_span operator ->
|
||||
Fixed shadowing warnings
|
||||
Changed etl::mem_cast to support bidirectional iterators
|
||||
Make 'packed' have better cross platform functionality
|
||||
|
||||
Fixes:
|
||||
#937 ETL_USING_LEGACY_VARIANT Is always getting evaluated to 1
|
||||
#940 Allow etl::observer notification without argument
|
||||
#942 Warning on pragma c++20-compat
|
||||
#951 Can't get call_if to work because of etl::optional
|
||||
#956 Fix build error (etl::circular_buffer)
|
||||
#957 Support heterogenous lookup for maps
|
||||
#959 Treat bitset with size_type
|
||||
#972 Template not allowed warning in parameter pack
|
||||
#979 QueuedMessageRouter does not work : message are not sent to queue
|
||||
#980 Documentation clarification: Add link from endianess to unaligned_type
|
||||
#982 Added return to etl::optional emplace, fixed typo
|
||||
#984 Update Base64 Documentation
|
||||
#986 Added const iterators to span
|
||||
#987 Fix test loop
|
||||
#992 Return reference from emplace() in etl::queue. Added return reference from stack::emplace
|
||||
#993 Need "lighter weight" ETL_ASSERT
|
||||
#997 Request: operator[ ] for containers can be configured to emit an exception
|
||||
#1000 Make ETL_TYPEDEF Trivially Copyable
|
||||
#1017 etl::max_element has undefined behavior if the range is empty
|
||||
#1016 Allow compile time CRC calculation
|
||||
#1019 UB when passing a temporary lambda to a delegate
|
||||
#1022 Request: Add option to disable non-lock-free atomics - Added is_always_lock_free member constant to etl::atomic
|
||||
#1030 Modify etl::message_packet to not require polymorphic messages
|
||||
#1031 etl::string is invalid if calling assign() with itself. Added additional checks for self assignment.
|
||||
#1032 Tasking Compiler Failure For parameter_pack.h
|
||||
|
||||
Pull Requests:
|
||||
#947 Remove unused git submodule config
|
||||
#965 Fix accident creation of a delegate to an rvalue delegate when copying/assigning from delegate with mismatching signature
|
||||
#985 Add uncopyable.h, class uncopyable
|
||||
#986 Added const iterators to span
|
||||
#989 Packed unaligned_type
|
||||
#990 Add contains() method to etl::unordered_map and etl::unordered_set
|
||||
#992 Return reference from emplace() in etl::queue
|
||||
#999 Add at_address() to etl::unaligned_type. Added etl::unaligned_type_ext instead at_address()
|
||||
#1001 Add max_item_size() to etl::ipool
|
||||
#1002 Add singleton_base
|
||||
#1005 Fixed memory.h: mem_copy, mem_move, mem_compare for pointers to const
|
||||
#1006 Fix arm64 signed char
|
||||
#1007 Fix fixed extent span empty()
|
||||
#1021 Some minor cleanup changes
|
||||
#1014 Added missing rational arithmetic functions from <ratio>
|
||||
#1027 Add etl::make_span()
|
||||
|
||||
===============================================================================
|
||||
20.39.4
|
||||
|
||||
#948 Bug in queue pop can break queue.empty()
|
||||
@ -13,6 +77,8 @@ Removed C++11 restriction on etl::observer::notification
|
||||
|
||||
Fixes:
|
||||
#917 unaligned_type doesn't compile with floating point types
|
||||
#923 Missing equality operator for class expected
|
||||
#930 Unused parameter warnings
|
||||
|
||||
Pull Requests:
|
||||
#946 Make include paths to private files relative
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
cmake_minimum_required(VERSION 3.10.0)
|
||||
project(etl_unit_tests LANGUAGES CXX)
|
||||
|
||||
#include(FetchContent)
|
||||
@ -410,6 +410,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
-Wuseless-cast
|
||||
-Wshadow
|
||||
-Wnull-dereference
|
||||
-g
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
11
test/data.h
11
test/data.h
@ -209,6 +209,13 @@ public:
|
||||
other.valid = false;
|
||||
}
|
||||
|
||||
TestDataM(const TestDataM&& other) noexcept
|
||||
: value(std::move(other.value))
|
||||
, valid(true)
|
||||
{
|
||||
other.valid = false;
|
||||
}
|
||||
|
||||
virtual ~TestDataM()
|
||||
{
|
||||
valid = false;
|
||||
@ -249,8 +256,8 @@ public:
|
||||
return valid;
|
||||
}
|
||||
|
||||
T value;
|
||||
bool valid;
|
||||
T value;
|
||||
mutable bool valid;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user