diff --git a/.circleci/config.yml b/.circleci/config.yml index 28e75cee..56da1208 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,26 +1,32 @@ version: 2 - jobs: build: docker: - - image: "debian:stretch" + - image: "rikorose/gcc-cmake:latest" + branches: + only: + - master + - development steps: - - checkout + - checkout: - run: - name: Installing SUDO - command: 'apt-get update && apt-get install -y sudo && rm -rf /var/lib/apt/lists/*' - - run: - name: Installing GCC - command: 'apt-get update && apt-get install -y gcc g++' - - run: - name: Install CMAKE - command: 'apt-get update && sudo apt-get install -y cmake' + name: Listing0 + command: 'ls -lrt' - run: name: Creating Build Files - command: 'cmake -H. -Bbuild' + command: 'cmake -Bbuild test/' - run: name: Creating Binary Files command: 'cmake --build build' + - run: + name: Listing1 + command: 'ls -lrt /root/project/build' + - run: + name: Listing2 + command: 'ls -lrt /root/project/build/CMakeFiles' + - run: + name: Listing3 + command: 'cat /root/project/build/CMakeFiles/CMakeOutput.log' - run: name: ETL Unit Testing - command: './bin/etl' \ No newline at end of file + command: './build/etl_tests' diff --git a/.gitattributes b/.gitattributes index 1ff0c423..28d19991 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,11 @@ ############################################################################### * text=auto +############################################################################### +# Declare files that will always have LF line endings on checkout. +############################################################################### +*.sh text eol=lf + ############################################################################### # Set default behavior for command prompt diff. # diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..9c999a1f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +patreon: etlcpp diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml new file mode 100644 index 00000000..35b012c1 --- /dev/null +++ b/.github/workflows/clang.yml @@ -0,0 +1,89 @@ +name: clang +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-clang-9-linux: + name: Clang-9 Linux + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + export CC=clang-9 + export CXX=clang++-9 + cmake -D BUILD_TESTS=ON ./ + clang --version + make + + - name: Run tests + run: ./test/etl_tests + + build-clang-9-linux-no-stl: + name: Clang-9 Linux - No STL + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-20.04] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + cmake -DBUILD_TESTS=ON -DNO_STL=ON ./ + gcc --version + make + + - name: Run tests + run: ./test/etl_tests + + build-clang-10-osx: + name: Clang-10 OSX + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-10.15] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -D BUILD_TESTS=ON ./ + clang --version + make + + - name: Run tests + run: ./test/etl_tests + + build-clang-10-osx-no-stl: + name: Clang-10 OSX - No STL + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-10.15] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + export CC=clang + export CXX=clang++ + cmake -D BUILD_TESTS=ON -DNO_STL=ON ./ + clang --version + make + + - name: Run tests + run: ./test/etl_tests diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml new file mode 100644 index 00000000..5e1ea8f1 --- /dev/null +++ b/.github/workflows/gcc.yml @@ -0,0 +1,45 @@ +name: gcc +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-gcc-linux: + name: GCC Linux + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, ubuntu-20.04] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + cmake -DBUILD_TESTS=ON ./ + gcc --version + make + + - name: Run tests + run: ./test/etl_tests + + build-gcc-linux-no-stl: + name: GCC Linux - No STL + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-18.04, ubuntu-20.04] + + steps: + - uses: actions/checkout@v2 + + - name: Build + run: | + cmake -DBUILD_TESTS=ON -DNO_STL=ON ./ + gcc --version + make + + - name: Run tests + run: ./test/etl_tests diff --git a/.github/workflows/vs2019.yml b/.github/workflows/vs2019.yml new file mode 100644 index 00000000..34023277 --- /dev/null +++ b/.github/workflows/vs2019.yml @@ -0,0 +1,51 @@ +name: vs2019 +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-windows-vs2019: + name: Windows VS2019 Debug + runs-on: [windows-latest] + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + + - name: Build + run: | + cmake -G "Visual Studio 16 2019" -DBUILD_TESTS=ON ./ + MSBuild.exe -version + MSBuild.exe etl.sln + + - name: Run tests + run: ./test/debug/etl_tests.exe + + build-windows-vs2019-no-stl: + name: Windows VS2019 Debug - No STL + runs-on: [windows-latest] + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + + - name: Build + run: | + cmake -G "Visual Studio 16 2019" -DBUILD_TESTS=ON -DNO_STL=ON ./ + MSBuild.exe -version + MSBuild.exe etl.sln + + - name: Run tests + run: ./test/debug/etl_tests.exe diff --git a/.gitignore b/.gitignore index 0fa14b13..45c37380 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ examples/ArmTimerCallbacks/Listings examples/ArmTimerCallbacks/Objects examples/ArmTimerCallbacks/DebugConfig build-test-Desktop_x86_windows_msvc2017_pe_32bit-Debug/unittest++/src +buildresults/ ################# ## Eclipse @@ -251,3 +252,37 @@ cmake-build-*/ unittest-cpp *.opendb +build-test-Desktop_x86_windows_msvc2017_pe_32bit-Debug +test/Logs +build-test-Desktop_x86_windows_msvc2019_pe_32bit-Debug +test/vs2019/.vs +Corel Auto-Preserve +.vscode +build-test-Clang_10-Debug +build-test-GCC-Debug +test/kdevelopbuild/unittest++ +test/random_clcg.csv +test/random_hash.csv +test/random_lcg.csv +test/random_lcg.csv +test/random_lcg.csv +test/random_lsfr.csv +test/random_lsfr.csv +test/random_mwc.csv +test/random_pcg.csv +test/random_pcg.csv +test/random_xorshift.csv +test/cmake_install.cmake +test/Makefile +test/vs2019/enc_temp_folder +test/vs2019/.leu +test/etl_test_log.txt +test/vs2019/Debug No Unit Tests +test/vs2019/multi_loop.csv +temp/create_arduino_library.py +examples/FunctionInterruptSimulation-Delegates/vs2019/.vs + +*.db-shm +test/vs2019/.vs/etl/v16/Browse.VC.db-wal +examples/SharedMessage/.vs +examples/QueuedMessageRouter/vs2019/.vs diff --git a/.vs/.gitignore b/.vs/.gitignore deleted file mode 100644 index 35226880..00000000 --- a/.vs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/slnx.sqlite diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json deleted file mode 100644 index 38c5f003..00000000 --- a/.vs/ProjectSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CurrentProjectSetting": "x86-Debug" -} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index 9e5a6885..00000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "ExpandedNodes": [ - "", - "\\include", - "\\include\\etl", - "\\test" - ], - "SelectedNode": "\\test\\test_to_string.cpp", - "PreviewInSolutionExplorer": false -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 72627167..eef6d0df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,57 +4,14 @@ cmake_minimum_required(VERSION 3.5.0) project(etl) -####################################################################### -# Define an option to allow consumers of the library to -# specify the profile they would like to compile to. If -# not explicitly set CMake will attempt to choose an appropriate -# profile based on the compiler -####################################################################### -set(ETL_PROFILE "DEFAULT" CACHE STRING "Defines what profile header to include. See https://www.etlcpp.com/setup.html" -) - option(BUILD_TESTS "Build unit tests" OFF) +option(NO_STL "No STL" OFF) add_library(etl INTERFACE) -target_include_directories(etl - INTERFACE - include - include/etl/profiles - ) - -if (${ETL_PROFILE} STREQUAL DEFAULT) - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(ETL_PROFILE "PROFILE_GCC_GENERIC") - - elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(ETL_PROFILE "PROFILE_CLANG_GENERIC") - - elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set(ETL_PROFILE "PROFILE_MSVC") - - elseif (CMAKE_CXX_COMPILER_ID MATCHES "ARMCC") - if (CXX_STANDARD EQUAL 11) - set(ETL_PROFILE "PROFILE_ARMV6") - else () - set(ETL_PROFILE "PROFILE_ARMV5") - endif() - elseif (CMAKE_CXX_COMPILER_ID MATCHES "TI") - set(ETL_PROFILE "PROFILE_TICC") - - else() - message(FATAL_ERROR "Can't generate default profile for compiler: ${CMAKE_CXX_COMPILER_ID}") - endif() -endif() - -message(STATUS "Compiling with ETL profile set to: ${ETL_PROFILE}") - -target_compile_definitions(etl - INTERFACE - ${ETL_PROFILE} - ) - +target_include_directories(etl SYSTEM INTERFACE include) +target_compile_definitions(etl INTERFACE) if (BUILD_TESTS) enable_testing() diff --git a/CMakeSettings.json b/CMakeSettings.json deleted file mode 100644 index 9d0eaab8..00000000 --- a/CMakeSettings.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "configurations": [ - { - "name": "x86-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ - "msvc_x86" - ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "-v", - "ctestCommandArgs": "" - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 3429ac9b..c8cc0936 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ Embedded Template Library (ETL) ------------------------- -AppVeyor -[![Build status](https://ci.appveyor.com/api/projects/status/b7jgecv7unqjw4u0/branch/master?svg=true)](https://ci.appveyor.com/project/jwellbelove/etl/branch/master) -[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3c14cd918ccf40008d0bcd7b083d5946)](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/jwellbelove/etl) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) -[![Github All Releases](https://img.shields.io/github/downloads/ETLCPP/etl/total.svg)]() - +![CI](https://github.com/ETLCPP/etl/workflows/vs2019/badge.svg) +![CI](https://github.com/ETLCPP/etl/workflows/gcc/badge.svg) +![CI](https://github.com/ETLCPP/etl/workflows/clang/badge.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3c14cd918ccf40008d0bcd7b083d5946)](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade) **Motivation** diff --git a/appveyor.yml b/appveyor.yml index b4f4dc4c..375e1e81 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ version: 1.0.{build} branches: only: - master -image: Visual Studio 2017 +image: Visual Studio 2019 configuration: - Debug - DebugNoSTL @@ -12,7 +12,7 @@ install: before_build: - cmd: git clone https://github.com/unittest-cpp/unittest-cpp.git c:\projects\unittest-cpp build: - project: test/vs2017/etl.vcxproj + project: test/vs2019/etl.vcxproj verbosity: minimal notifications: - provider: Webhook @@ -20,4 +20,5 @@ notifications: method: POST on_build_success: true on_build_failure: true - on_build_status_changed: true \ No newline at end of file + on_build_status_changed: true + \ No newline at end of file diff --git a/arduino/Embedded_Template_Library.h b/arduino/Embedded_Template_Library.h new file mode 100644 index 00000000..b7ac4789 --- /dev/null +++ b/arduino/Embedded_Template_Library.h @@ -0,0 +1,80 @@ + +#ifndef ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED +#define ETL_EMBEDDED_TEMPLATE_LIBRARY_INCLUDED + +#if defined(TEENSYDUINO) + + #if defined(__AVR_ATmega32U4__) + #define ARDUINO_BOARD "Teensy 2.0" + #elif defined(__AVR_AT90USB1286__) + #define ARDUINO_BOARD "Teensy++ 2.0" + #elif defined(__MK20DX128__) + #define ARDUINO_BOARD "Teensy 3.0" + #elif defined(__MK20DX256__) + #define ARDUINO_BOARD "Teensy 3.2" // and Teensy 3.1 + #elif defined(__MKL26Z64__) + #define ARDUINO_BOARD "Teensy LC" + #elif defined(__MK64FX512__) + #define ARDUINO_BOARD "Teensy 3.5" + #elif defined(__MK66FX1M0__) + #define ARDUINO_BOARD "Teensy 3.6" + #else + #define ARDUINO_BOARD "Unknown" + #endif + +#else // --------------- Arduino ------------------ + + #if defined(ARDUINO_AVR_ADK) + #define ARDUINO_BOARD "Mega Adk" + #elif defined(ARDUINO_AVR_BT) + #define ARDUINO_BOARD "Bt" + #elif defined(ARDUINO_AVR_DUEMILANOVE) + #define ARDUINO_BOARD "Duemilanove" + #elif defined(ARDUINO_AVR_ESPLORA) + #define ARDUINO_BOARD "Esplora" + #elif defined(ARDUINO_AVR_ETHERNET) + #define ARDUINO_BOARD "Ethernet" + #elif defined(ARDUINO_AVR_FIO) + #define ARDUINO_BOARD "Fio" + #elif defined(ARDUINO_AVR_GEMMA) + #define ARDUINO_BOARD "Gemma" + #elif defined(ARDUINO_AVR_LEONARDO) + #define ARDUINO_BOARD "Leonardo" + #elif defined(ARDUINO_AVR_LILYPAD) + #define ARDUINO_BOARD "Lilypad" + #elif defined(ARDUINO_AVR_LILYPAD_USB) + #define ARDUINO_BOARD "Lilypad Usb" + #elif defined(ARDUINO_AVR_MEGA) + #define ARDUINO_BOARD "Mega" + #elif defined(ARDUINO_AVR_MEGA2560) + #define ARDUINO_BOARD "Mega 2560" + #elif defined(ARDUINO_AVR_MICRO) + #define ARDUINO_BOARD "Micro" + #elif defined(ARDUINO_AVR_MINI) + #define ARDUINO_BOARD "Mini" + #elif defined(ARDUINO_AVR_NANO) + #define ARDUINO_BOARD "Nano" + #elif defined(ARDUINO_AVR_NG) + #define ARDUINO_BOARD "NG" + #elif defined(ARDUINO_AVR_PRO) + #define ARDUINO_BOARD "Pro" + #elif defined(ARDUINO_AVR_ROBOT_CONTROL) + #define ARDUINO_BOARD "Robot Ctrl" + #elif defined(ARDUINO_AVR_ROBOT_MOTOR) + #define ARDUINO_BOARD "Robot Motor" + #elif defined(ARDUINO_AVR_UNO) + #define ARDUINO_BOARD "Uno" + #elif defined(ARDUINO_AVR_YUN) + #define ARDUINO_BOARD "Yun" + #elif defined(ARDUINO_SAM_DUE) + #define ARDUINO_BOARD "Due" + #elif defined(ARDUINO_SAMD_ZERO) + #define ARDUINO_BOARD "Zero" + #elif defined(ARDUINO_ARC32_TOOLS) + #define ARDUINO_BOARD "101" + #else + #define ARDUINO_BOARD "Unknown" + #endif +#endif + +#endif \ No newline at end of file diff --git a/arduino/create_arduino_library.py b/arduino/create_arduino_library.py new file mode 100644 index 00000000..b74549e1 --- /dev/null +++ b/arduino/create_arduino_library.py @@ -0,0 +1,72 @@ + +import shutil +import os + +# Assumes this folder structure. +# Folder Variable +# --------------------------------------- +# etl etl_dir +# arduino arduino_dir +# include include_dir +# etl-arduino etl_arduino_dir +# src etl_arduino_src_dir + +print('') +print('Copy ETL files to the etl-arduino repository') +print('') + +# Get the current path of the script +arduino_dir = os.path.dirname(__file__) +print('arduino_dir = ', arduino_dir) + +# Get the root folder of the ETL +etl_dir = os.path.dirname(arduino_dir) +print('etl_dir = ', etl_dir) + +# Get the ETL repository folder +include_dir = os.path.join(etl_dir, 'include') +print('include_dir = ', include_dir) + +# Get the root folder of both repositories +common_dir = os.path.dirname(etl_dir) +print('common_dir = ', common_dir) + +# Get the ETL Arduino repository folder +etl_arduino_dir = os.path.join(common_dir, 'etl-arduino') +print('etl_arduino_dir = ', etl_arduino_dir) + +# Get the ETL Arduino src repository folder +etl_arduino_src_dir = os.path.join(etl_arduino_dir, 'src') +print('etl_arduino_src_dir = ', etl_arduino_src_dir) + +print('') + +# Copy the library properties +filename = 'library.properties' +source = os.path.join(etl_dir, filename) +destination = os.path.join(etl_arduino_dir, filename) +print('Copy the library properties') +print(' From :', source) +print(' To :', destination) +shutil.copyfile(source, destination) + +print('') + +# Copy the Arduino ETL header +filename = 'Embedded_Template_Library.h' +source = os.path.join(arduino_dir, filename) +destination = os.path.join(etl_arduino_src_dir, filename) +print('Copy the Arduino ETL header') +print(' From :', source) +print(' To :', destination) +shutil.copyfile(source, destination) + +print('') + +# Copy the ETL headers +source = include_dir +destination = etl_arduino_src_dir +print('Copy the ETL headers') +print(' From :', source) +print(' To :', destination) +shutil.copytree(source, destination, dirs_exist_ok = True) diff --git a/conanfile.py b/conanfile.py index 79a6824d..100decc6 100755 --- a/conanfile.py +++ b/conanfile.py @@ -20,10 +20,10 @@ class EmbeddedTemplateLibraryConan(ConanFile): name = "embedded-template-library" version = get_version_from_git_tag() license = "MIT" - author = "John Wellbelove " + author = "John Wellbelove " url = "https://github.com/ETLCPP/etl" description = "A C++ template library for embedded applications" - topics = ("embedded", "template", "container") + topics = ("C++", "embedded", "template", "container", "utility", "framework", "messaging") # Source info scm = { diff --git a/etl.ico b/etl.ico deleted file mode 100644 index fe0e3665..00000000 Binary files a/etl.ico and /dev/null differ diff --git a/etl.png b/etl.png deleted file mode 100644 index ca5e3de9..00000000 Binary files a/etl.png and /dev/null differ diff --git a/etl.pspimage b/etl.pspimage deleted file mode 100644 index a5329e63..00000000 Binary files a/etl.pspimage and /dev/null differ diff --git a/etl.xar b/etl.xar deleted file mode 100644 index cbfaa863..00000000 Binary files a/etl.xar and /dev/null differ diff --git a/etl16.png b/etl16.png deleted file mode 100644 index 44cad996..00000000 Binary files a/etl16.png and /dev/null differ diff --git a/etl48.png b/etl48.png deleted file mode 100644 index 03dcffbb..00000000 Binary files a/etl48.png and /dev/null differ diff --git a/examples/ArmTimerCallbacks - C++/etl_profile.h b/examples/ArmTimerCallbacks - C++/etl_profile.h index dc157287..84bbd550 100644 --- a/examples/ArmTimerCallbacks - C++/etl_profile.h +++ b/examples/ArmTimerCallbacks - C++/etl_profile.h @@ -10,6 +10,6 @@ #define ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK #define ETL_NO_STL -#include "etl/profiles/auto.h" +//#include "etl/profiles/auto.h" #endif diff --git a/examples/Debounce/Debounce.sln b/examples/Debounce/Debounce.sln deleted file mode 100644 index 6d3f1698..00000000 --- a/examples/Debounce/Debounce.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Debounce", "Debounce.vcxproj", "{2D9F7027-A2E4-4558-869E-A09815D85E02}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x64.ActiveCfg = Debug|x64 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x64.Build.0 = Debug|x64 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x86.ActiveCfg = Debug|Win32 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Debug|x86.Build.0 = Debug|Win32 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x64.ActiveCfg = Release|x64 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x64.Build.0 = Release|x64 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x86.ActiveCfg = Release|Win32 - {2D9F7027-A2E4-4558-869E-A09815D85E02}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/examples/Debounce/Debounce.vcxproj.filters b/examples/Debounce/Debounce.vcxproj.filters deleted file mode 100644 index ac927ede..00000000 --- a/examples/Debounce/Debounce.vcxproj.filters +++ /dev/null @@ -1,25 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Header Files - - - \ No newline at end of file diff --git a/examples/FunctionInterruptSimulation-Delegates/CMakeLists.txt b/examples/FunctionInterruptSimulation-Delegates/CMakeLists.txt new file mode 100644 index 00000000..68a3639c --- /dev/null +++ b/examples/FunctionInterruptSimulation-Delegates/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(FunctionInterruptSimulation) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES FunctionInterruptSimulation.cpp) + +add_executable(FunctionInterruptSimulation ${SOURCE_FILES}) +target_include_directories(FunctionInterruptSimulation + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET FunctionInterruptSimulation PROPERTY CXX_STANDARD 17) + diff --git a/examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.sln b/examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.sln new file mode 100644 index 00000000..26180392 --- /dev/null +++ b/examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.16 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FunctionInterruptSimulation-Delegates", "FunctionInterruptSimulation-Delegates.vcxproj", "{5157DB15-C255-4E47-9FB1-AF388437F90F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x64.ActiveCfg = Debug|x64 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x64.Build.0 = Debug|x64 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x86.ActiveCfg = Debug|Win32 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x86.Build.0 = Debug|Win32 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x64.ActiveCfg = Release|x64 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x64.Build.0 = Release|x64 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x86.ActiveCfg = Release|Win32 + {5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {260225EB-60CB-44CC-A60C-16A23BBC10EB} + EndGlobalSection +EndGlobal diff --git a/examples/Debounce/Debounce.vcxproj b/examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.vcxproj similarity index 55% rename from examples/Debounce/Debounce.vcxproj rename to examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.vcxproj index e6162ff3..67906a09 100644 --- a/examples/Debounce/Debounce.vcxproj +++ b/examples/FunctionInterruptSimulation-Delegates/vs2019/FunctionInterruptSimulation-Delegates.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -18,37 +18,45 @@ x64 + + + + + + - {2D9F7027-A2E4-4558-869E-A09815D85E02} - Debounce - 8.1 + 15.0 + {5157DB15-C255-4E47-9FB1-AF388437F90F} + Win32Proj + FunctionInterruptSimulation + 10.0 Application true - v140 - MultiByte + v142 + Unicode Application false - v140 + v142 true - MultiByte + Unicode Application true - v140 - MultiByte + v142 + Unicode Application false - v140 + v142 true - MultiByte + Unicode @@ -68,58 +76,81 @@ - + + true + + + true + + + false + + + false + + Use Level3 Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino\avr;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\cores\arduino\USB;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\variants\arduino_zero;D:\Users\John\Documents\Programming\GitHub\etl\examples\Debounce;C:\Program Files (x86)\Arduino\libraries;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\libraries;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\qdmsbpkv.c4h\Micro Platforms\default\debuggers;D:\Users\John\Documents\Programming\Arduino\libraries;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/CMSIS/Include/;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel/Device/ATMEL/;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3\arm-none-eabi;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\c++\4.8.3\bits;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\arm-none-eabi\include\sys;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.5\system;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd/avr;C:\Users\John\AppData\Local\arduino15\packages\arduino\hardware\samd/usb;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1\lib\gcc\arm-none-eabi\4.8.3\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\CMSIS\include;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\component;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\instance;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\pio;C:\Users\John\AppData\Local\arduino15\packages\arduino\tools\CMSIS\4.0.0-atmel\Device\ATMEL\samd21\include\component;%(AdditionalIncludeDirectories) - D:\Users\John\Documents\Programming\GitHub\etl\examples\Debounce\__vm\.Debounce.vsarduino.h;%(ForcedIncludeFiles) - F_CPU=48000000L;ARDUINO=10607;ARDUINO_SAMD_ZERO;ARDUINO_ARCH_SAMD;__SAMD21G18A__;USB_VID=0x2341;USB_PID=0x804d;USBCON;__cplusplus=201103L;%(PreprocessorDefinitions) + ../../../src + + Console + true + + NotUsing Level3 Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + ../../../include;%(AdditionalIncludeDirectories) + stdcpp17 + + Console + true + + Use Level3 MaxSpeed true true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + Console true true + true + Use Level3 MaxSpeed true true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + Console true true + true - - - CppCode - - - - - diff --git a/examples/FunctionInterruptSimulation/CMakeLists.txt b/examples/FunctionInterruptSimulation/CMakeLists.txt new file mode 100644 index 00000000..68a3639c --- /dev/null +++ b/examples/FunctionInterruptSimulation/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(FunctionInterruptSimulation) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES FunctionInterruptSimulation.cpp) + +add_executable(FunctionInterruptSimulation ${SOURCE_FILES}) +target_include_directories(FunctionInterruptSimulation + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET FunctionInterruptSimulation PROPERTY CXX_STANDARD 17) + diff --git a/examples/QueuedFSM/CMakeLists.txt b/examples/QueuedFSM/CMakeLists.txt new file mode 100644 index 00000000..5cd13b05 --- /dev/null +++ b/examples/QueuedFSM/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(queued_fsm) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES QueuedFSM.cpp) + +add_executable(queued_fsm ${SOURCE_FILES}) +target_include_directories(queued_fsm + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET queued_fsm PROPERTY CXX_STANDARD 17) + diff --git a/examples/QueuedMessageRouter/CMakeLists.txt b/examples/QueuedMessageRouter/CMakeLists.txt new file mode 100644 index 00000000..2c11fe31 --- /dev/null +++ b/examples/QueuedMessageRouter/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(queued_message_router) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES QueuedMessageRouter.cpp) + +add_executable(queued_message_router ${SOURCE_FILES}) +target_include_directories(queued_message_router + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET queued_message_router PROPERTY CXX_STANDARD 17) + diff --git a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp index f635709e..a392db95 100644 --- a/examples/QueuedMessageRouter/QueuedMessageRouter.cpp +++ b/examples/QueuedMessageRouter/QueuedMessageRouter.cpp @@ -67,13 +67,16 @@ public: if (accepts(msg_)) { // Place in queue. + + Item item(&sender_, msg_); + queue.emplace(&sender_, msg_); - std::cout << "Queueing message " << int(msg_.message_id) << std::endl; + std::cout << "Queueing message " << int(msg_.get_message_id()) << std::endl; } else { - std::cout << "Ignoring message " << int(msg_.message_id) << std::endl; + std::cout << "Ignoring message " << int(msg_.get_message_id()) << std::endl; } } @@ -85,7 +88,7 @@ public: Item& item = queue.front(); etl::imessage& msg = item.packet.get(); etl::imessage_router& sender = *item.sender; - std::cout << "Processing message " << int(msg.message_id) << std::endl; + std::cout << "Processing message " << int(msg.get_message_id()) << std::endl; // Call the base class's receive function. // This will route it to the correct on_receive handler. @@ -98,25 +101,25 @@ public: //*************************************************************************** void on_receive(etl::imessage_router& sender, const Message1& msg) { - std::cout << " Received message " << int(msg.message_id) << " : '" << msg.i << "'" << std::endl; + std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.i << "'" << std::endl; } //*************************************************************************** void on_receive(etl::imessage_router& sender, const Message2& msg) { - std::cout << " Received message " << int(msg.message_id) << " : '" << msg.d << "'" << std::endl; + std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.d << "'" << std::endl; } //*************************************************************************** void on_receive(etl::imessage_router& sender, const Message3& msg) { - std::cout << " Received message " << int(msg.message_id) << " : '" << msg.s << "'" << std::endl; + std::cout << " Received message " << int(msg.get_message_id()) << " : '" << msg.s << "'" << std::endl; } //*************************************************************************** void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg) { - std::cout << " Received unknown message " << int(msg.message_id) << std::endl; + std::cout << " Received unknown message " << int(msg.get_message_id()) << std::endl; } private: diff --git a/examples/QueuedMessageRouter/vs2017/etl_profile.h b/examples/QueuedMessageRouter/etl_profile.h similarity index 91% rename from examples/QueuedMessageRouter/vs2017/etl_profile.h rename to examples/QueuedMessageRouter/etl_profile.h index c96719fd..9839404e 100644 --- a/examples/QueuedMessageRouter/vs2017/etl_profile.h +++ b/examples/QueuedMessageRouter/etl_profile.h @@ -33,12 +33,8 @@ SOFTWARE. #define ETL_THROW_EXCEPTIONS #define ETL_VERBOSE_ERRORS -#define ETL_CHECK_PUSH_POP -#define ETL_ISTRING_REPAIR_ENABLE -#define ETL_IVECTOR_REPAIR_ENABLE -#define ETL_IDEQUE_REPAIR_ENABLE -#ifdef _MSC_VER +#if defined(_MSC_VER) #include "etl/profiles/msvc_x86.h" #else #include "etl/profiles/gcc_windows_x86.h" diff --git a/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite b/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite deleted file mode 100644 index 2572d76e..00000000 Binary files a/examples/QueuedMessageRouter/vs2017/.vs/QueuedMessageRouter.sqlite and /dev/null differ diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters b/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters deleted file mode 100644 index ef62273b..00000000 --- a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj.filters +++ /dev/null @@ -1,27 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.sln b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.sln similarity index 100% rename from examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.sln rename to examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.sln diff --git a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj similarity index 96% rename from examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj rename to examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj index b697a59e..65dad150 100644 --- a/examples/QueuedMessageRouter/vs2017/QueuedMessageRouter.vcxproj +++ b/examples/QueuedMessageRouter/vs2019/QueuedMessageRouter.vcxproj @@ -23,32 +23,32 @@ {2BB47D48-5EFC-4C38-B2BE-002172F00E3B} Win32Proj QueuedMessageRouter - 10.0.18362.0 + 10.0 Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode Application true - v141 + v142 Unicode Application false - v141 + v142 true Unicode @@ -150,7 +150,7 @@ - + diff --git a/examples/Scheduler/CMakeLists.txt b/examples/Scheduler/CMakeLists.txt new file mode 100644 index 00000000..98b79c97 --- /dev/null +++ b/examples/Scheduler/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(scheduler) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES Scheduler.cpp) + +add_executable(scheduler ${SOURCE_FILES}) +target_include_directories(scheduler + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET scheduler PROPERTY CXX_STANDARD 17) + diff --git a/examples/Scheduler/Scheduler.cpp b/examples/Scheduler/Scheduler.cpp new file mode 100644 index 00000000..015822ae --- /dev/null +++ b/examples/Scheduler/Scheduler.cpp @@ -0,0 +1,184 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 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. +******************************************************************************/ + +//***************************************************************************** +// This example demonstrates the basic method to schedule tasks. +// Experiment with the different scheduling policies. +//***************************************************************************** + +#include "etl/scheduler.h" +#include "etl/task.h" +#include "etl/function.h" + +#include +#include + +//***************************************************************************** +// Task 1. Lowest priority. +//***************************************************************************** +class Task1 : public etl::task +{ +public: + + //************************************* + Task1() + : task(1) + , work(3) + { + + } + + //************************************* + uint32_t task_request_work() const + { + return work; // How much work do we still have to do? This could be a message queue length. + } + + //************************************* + void task_process_work() + { + std::cout << "Task1 : Process work : " << work << std::endl; + --work; + } + +private: + + uint32_t work; +}; + +//***************************************************************************** +// Task 2. Highest priority. +//***************************************************************************** +class Task2 : public etl::task +{ +public: + + //************************************* + Task2() + : task(2) + , work(4) + { + + } + + //************************************* + uint32_t task_request_work() const + { + return work; // How much work do we still have to do? This could be a message queue length. + } + + //************************************* + void task_process_work() + { + std::cout << "Task2 : Process work : " << work << std::endl; + --work; + } + +private: + + uint32_t work; +}; + +//***************************************************************************** +// The idle handler. +//***************************************************************************** +class Idle +{ +public: + + //************************************* + Idle(etl::ischeduler& scheduler_) + : scheduler(scheduler_) + { + + } + + //************************************* + void IdleCallback() + { + std::cout << "Idle callback" << std::endl; + scheduler.exit_scheduler(); + std::cout << "Exiting the scheduler" << std::endl; + } + +private: + + etl::ischeduler& scheduler; +}; + +//***************************************************************************** +// The watchdog handler. +//***************************************************************************** +void WatchdogCallback() +{ + std::cout << "Watchdog callback" << std::endl; +} + +//***************************************************************************** +// The scheduler. +// Maximum of two tasks. +// +// Try the other scheduler policies to see how scheduling differs. +// etl::scheduler_policy_sequential_single +// etl::scheduler_policy_sequential_multiple +// etl::scheduler_policy_highest_priority +// etl::scheduler_policy_most_work +//***************************************************************************** +class Scheduler : public etl::scheduler +{ +}; + +//***************************************************************************** +// The test application. +//***************************************************************************** +int main() +{ + Scheduler scheduler; + + Task1 task1; + Task2 task2; + + Idle idleHandler(scheduler); + + etl::function_mv idleCallback(idleHandler); // Member function, no parameters, returning void. + etl::function_fv watchdogCallback; // Global function, no parameters, returning void. + + scheduler.add_task(task1); + scheduler.add_task(task2); + scheduler.set_idle_callback(idleCallback); + scheduler.set_watchdog_callback(watchdogCallback); + + std::cout << "Starting the scheduler" << std::endl; + + scheduler.start(); + + std::cout << "Exiting the application" << std::endl; + + return 0; +} + diff --git a/include/etl/profiles/etl_profile.h b/examples/Scheduler/etl_profile.h similarity index 59% rename from include/etl/profiles/etl_profile.h rename to examples/Scheduler/etl_profile.h index bce6871d..735de7fc 100644 --- a/include/etl/profiles/etl_profile.h +++ b/examples/Scheduler/etl_profile.h @@ -7,7 +7,7 @@ Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com -Copyright(c) 2017 jwellbelove, scott-eddy +Copyright(c) 2020 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 @@ -27,38 +27,17 @@ 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_PROFILE_H__ #define __ETL_PROFILE_H__ -#if defined(PROFILE_MSVC) - #include "msvc_x86.h" -#elif defined(PROFILE_GCC_GENERIC) - #include "gcc_generic.h" -#elif defined(PROFILE_GCC_LINUX_X86) - #include "gcc_linux_x86.h" -#elif defined(PROFILE_GCC_WINDOWS_X86) - #include "gcc_windows_x86.h" -#elif defined(PROFILE_CLANG_GENERIC) - #include "clang_generic.h" -#elif defined(PROFILE_ARM_V5_GENERIC) - #include "armv5.h" -#elif defined(PROFILE_ARM_V6_GENERIC) - #include "armv6.h" -#elif defined(PROFILE_ARDUINO) - #include "arduino_arm.h" -#elif defined(PROFILE_TICC) - #include "ticc.h" -#elif defined(PROFILE_CPP03_GENERIC) - #include "cpp03.h" -#elif defined(PROFILE_CPP11_GENERIC) - #include "cpp11.h" -#elif defined(PROFILE_CPP14_GENERIC) - #include "cpp14.h" -#elif defined(PROFILE_CPP17_GENERIC) - #include "cpp17.h" -#elif defined(PROFILE_CUSTOM) - #include "custom_profile.h" -#else - #include "auto.h" + +#define ETL_THROW_EXCEPTIONS +#define ETL_VERBOSE_ERRORS + +#if defined(_MSC_VER) + #include "etl/profiles/msvc_x86.h" +#elif defined(__GNUC__) + #include "etl/profiles/gcc_generic.h" #endif -#endif // __ETL_PROFILE_H_ +#endif diff --git a/examples/Scheduler/vs2017/Scheduler.sln b/examples/Scheduler/vs2017/Scheduler.sln new file mode 100644 index 00000000..994c596f --- /dev/null +++ b/examples/Scheduler/vs2017/Scheduler.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Scheduler", "Scheduler.vcxproj", "{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x64.ActiveCfg = Debug|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.ActiveCfg = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.Build.0 = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.ActiveCfg = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.Build.0 = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.ActiveCfg = Release|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {98B87835-6672-45D4-95BF-CC5C22C87D2C} + EndGlobalSection +EndGlobal diff --git a/examples/Scheduler/vs2017/Scheduler.vcxproj b/examples/Scheduler/vs2017/Scheduler.vcxproj new file mode 100644 index 00000000..c70dabcd --- /dev/null +++ b/examples/Scheduler/vs2017/Scheduler.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B} + Win32Proj + Scheduler + 10.0.18362.0 + + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + Application + true + v141 + Unicode + + + Application + false + v141 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + stdcpp17 + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + + stdcpp17 + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/Scheduler/vs2019/Scheduler.sln b/examples/Scheduler/vs2019/Scheduler.sln new file mode 100644 index 00000000..994c596f --- /dev/null +++ b/examples/Scheduler/vs2019/Scheduler.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Scheduler", "Scheduler.vcxproj", "{2BB47D48-5EFC-4C38-B2BE-002172F00E3B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x64.ActiveCfg = Debug|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.ActiveCfg = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Debug|x86.Build.0 = Debug|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.ActiveCfg = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x64.Build.0 = Release|x64 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.ActiveCfg = Release|Win32 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {98B87835-6672-45D4-95BF-CC5C22C87D2C} + EndGlobalSection +EndGlobal diff --git a/examples/Scheduler/vs2019/Scheduler.vcxproj b/examples/Scheduler/vs2019/Scheduler.vcxproj new file mode 100644 index 00000000..8e00efa6 --- /dev/null +++ b/examples/Scheduler/vs2019/Scheduler.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {2BB47D48-5EFC-4C38-B2BE-002172F00E3B} + Win32Proj + Scheduler + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + stdcpp17 + + + Console + true + + + + + NotUsing + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../../../include;../vs2017 + + stdcpp17 + + + Console + true + + + + + Use + Level3 + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Use + Level3 + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + %(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/SharedMessage/CMakeLists.txt b/examples/SharedMessage/CMakeLists.txt new file mode 100644 index 00000000..eb3f6aa1 --- /dev/null +++ b/examples/SharedMessage/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.5.0) +project(SharedMessage) + +add_definitions(-DETL_DEBUG) + +include_directories(${UTPP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/../../include) + +set(SOURCE_FILES SharedMessage.cpp) + +add_executable(SharedMessage ${SOURCE_FILES}) +target_include_directories(SharedMessage + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +set_property(TARGET SharedMessage PROPERTY CXX_STANDARD 17) + diff --git a/examples/SharedMessage/SharedMessage.cpp b/examples/SharedMessage/SharedMessage.cpp new file mode 100644 index 00000000..8f67bf13 --- /dev/null +++ b/examples/SharedMessage/SharedMessage.cpp @@ -0,0 +1,285 @@ +//***************************************************************************** +// Shared message example +//***************************************************************************** + +#include "etl/shared_message.h" +#include "etl/message.h" +#include "etl/reference_counted_message_pool.h" +#include "etl/message_router.h" +#include "etl/message_bus.h" +#include "etl/fixed_sized_memory_block_allocator.h" +#include "etl/queue.h" + +#include +#include +#include +#include + +constexpr etl::message_router_id_t RouterId1 = 1U; +constexpr etl::message_router_id_t RouterId2 = 2U; + +//***************************************************************************** +// Message1 +//***************************************************************************** +struct Message1 : public etl::message<1> +{ + Message1(std::string s_) + : s(s_) + { + + } + + std::string s; +}; + +//***************************************************************************** +// Message2 +//***************************************************************************** +struct Message2 : public etl::message<2> +{ + Message2(std::string s_) + : s(s_) + { + + } + + std::string s; + char data[100]; +}; + +//***************************************************************************** +// Message3 +//***************************************************************************** +struct Message3 : public etl::message<3> +{ + Message3(std::string s_) + : s(s_) + { + + } + + std::string s; +}; + +//***************************************************************************** +// Prints the shared message +//***************************************************************************** +void Print(const std::string& prefix, etl::shared_message sm) +{ + std::cout << prefix << " : Message Id = " << int(sm.get_message().get_message_id()) << "\n"; +} + +//***************************************************************************** +// This router accepts Message1, Message2 and Message3 types. +// If a shared message it received, it will be processed immediately. +//***************************************************************************** +class MessageRouter1 : public etl::message_router +{ +public: + + //**************************************** + MessageRouter1() + : message_router(RouterId1) + { + } + + //**************************************** + void on_receive(const Message1& msg) + { + std::cout << "MessageRouter1 : on_receive Message1 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive(const Message2& msg) + { + std::cout << "MessageRouter1 : on_receive Message2 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive(const Message3& msg) + { + std::cout << "MessageRouter1 : on_receive Message3 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive_unknown(const etl::imessage& msg) + { + std::cout << "MessageRouter1 : on_receive Unknown\n"; + } +}; + +//***************************************************************************** +// This router accepts Message1, Message2 and Message3 types. +// If a shared message it received it will queue them. +// The messages will be processed when process_queue() is called. +//***************************************************************************** +class MessageRouter2 : public etl::message_router +{ +public: + + using base_t = etl::message_router; + + //**************************************** + MessageRouter2() + : message_router(RouterId2) + { + } + + using base_t::receive; + + //**************************************** + // Overridden receive. + // Puts the shared messages into a queue. + void receive(etl::shared_message shared_msg) override + { + if (!queue.full()) + { + Print("MessageRouter2 : Queueing shared message", shared_msg); + + queue.push(shared_msg); + } + } + + //**************************************** + // Processes the queued shared messages. + void process_queue() + { + while (!queue.empty()) + { + // Get the shared message from the queue. + etl::shared_message shared_msg = queue.front(); + + Print("MessageRouter2 : Process queued shared message", shared_msg); + + // Send it to the base implementation for routing. + base_t::receive(shared_msg); + + queue.pop(); + } + } + + //**************************************** + void on_receive(const Message1& msg) + { + std::cout << "MessageRouter2 : on_receive Message1 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive(const Message2& msg) + { + std::cout << "MessageRouter2 : on_receive Message2 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive(const Message3& msg) + { + std::cout << "MessageRouter2 : on_receive Message3 : " << msg.s << "\n"; + } + + //**************************************** + void on_receive_unknown(const etl::imessage& msg) + { + std::cout << "MessageRouter2 : on_receive Unknown\n"; + } + +private: + + etl::queue queue; +}; + +//***************************************************************************** +// A message bus that can accomodate two subscribers. +//***************************************************************************** +struct Bus : public etl::message_bus<2U> +{ +}; + +//***************************************************************************** +// Define the routers and bus. +//***************************************************************************** +MessageRouter1 router1; +MessageRouter2 router2; +Bus bus; + +//***************************************************************************** +// The thread safe message pool. Uses atomic uint32_t for counting. +class MessagePool : public etl::reference_counted_message_pool +{ +public: + + MessagePool(etl::imemory_block_allocator& allocator) + : reference_counted_message_pool(allocator) + { + } + + // Called before the memory block allocator is accessed. + void lock() override + { + mut.lock(); + } + + // Called after the memory block allocator has been accessed. + void unlock() override + { + mut.unlock(); + } + +private: + + std::mutex mut; +}; + +//***************************************************************************** +// The memory block allocator that supplies the pool with memory +// to store reference counted messages in. + +// The reference counted message parameters type for the messages we will use. +using message_parameters_small = MessagePool::pool_message_parameters; +using message_parameters_large = MessagePool::pool_message_parameters; + +constexpr size_t max_size_small = message_parameters_small::max_size; +constexpr size_t max_alignment_small = message_parameters_small::max_alignment; + +constexpr size_t max_size_large = message_parameters_large::max_size; +constexpr size_t max_alignment_large = message_parameters_large::max_alignment; + +// A fixed memory block allocator for 4 items, using the parameters from the smaller messages. +etl::fixed_sized_memory_block_allocator memory_allocator; + +// A fixed memory block allocator for 4 items, using the parameters from the larger message. +etl::fixed_sized_memory_block_allocator memory_allocator_successor; + +//***************************************************************************** +// The pool that supplies reference counted messages. +// Uses memory_allocator as its allocator. +//***************************************************************************** +MessagePool message_pool(memory_allocator); + +//***************************************************************************** +// A statically allocated reference counted message that is never allocated or released by a pool. +// Contains a copy of Message3("Three"). +//***************************************************************************** +etl::persistent_message pm3(Message3("Three")); + +//***************************************************************************** +int main() +{ + // If memory_allocator can't allocate, then try memory_allocator_successor. + memory_allocator.set_successor(memory_allocator_successor); + + Message1 m1("One"); + Message2 m2("Two"); + + etl::shared_message sm1(message_pool, m1); // Created a shared message by allocating a reference counted message from message_pool containing a copy of m1. + etl::shared_message sm2(message_pool, m2); // Created a shared message by allocating a reference counted message from message_pool containing a copy of m2. + etl::shared_message sm3(pm3); // Created a shared message from a statically allocated persistent message. + + bus.subscribe(router1); // Subscribe router1 to the bus. + bus.subscribe(router2); // Subscribe router2 to the bus. + + bus.receive(sm1); // Send sm1 to the bus for distribution to the routers. + bus.receive(sm2); // Send sm2 to the bus for distribution to the routers. + bus.receive(sm3); // Send sm3 to the bus for distribution to the routers. + + router2.process_queue(); // Allow router2 to process its queued messages. +} diff --git a/examples/SharedMessage/SharedMessage.sln b/examples/SharedMessage/SharedMessage.sln new file mode 100644 index 00000000..fec1c6e1 --- /dev/null +++ b/examples/SharedMessage/SharedMessage.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedMessage", "SharedMessage.vcxproj", "{0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Debug|x64.ActiveCfg = Debug|x64 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Debug|x64.Build.0 = Debug|x64 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Debug|x86.ActiveCfg = Debug|Win32 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Debug|x86.Build.0 = Debug|Win32 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Release|x64.ActiveCfg = Release|x64 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Release|x64.Build.0 = Release|x64 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Release|x86.ActiveCfg = Release|Win32 + {0BDB4F2A-47E7-4105-A66A-6DFF8A76587B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F7B7515D-19FA-42D4-9BA2-5F85A7FB7779} + EndGlobalSection +EndGlobal diff --git a/examples/SharedMessage/SharedMessage.vcxproj b/examples/SharedMessage/SharedMessage.vcxproj new file mode 100644 index 00000000..24249971 --- /dev/null +++ b/examples/SharedMessage/SharedMessage.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {0bdb4f2a-47e7-4105-a66a-6dff8a76587b} + SharedMessage + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + D:\Users\John\Documents\Programming\GitHub\etl\include;%(AdditionalIncludeDirectories) + stdcpp17 + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/SharedMessage/SharedMessage.vcxproj.filters b/examples/SharedMessage/SharedMessage.vcxproj.filters new file mode 100644 index 00000000..673bfd20 --- /dev/null +++ b/examples/SharedMessage/SharedMessage.vcxproj.filters @@ -0,0 +1,66 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/examples/SharedMessage/etl_profile.h b/examples/SharedMessage/etl_profile.h new file mode 100644 index 00000000..e69de29b diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index 2cf75c1d..00000000 Binary files a/favicon.ico and /dev/null differ diff --git a/file.txt b/file.txt new file mode 100644 index 00000000..e69de29b diff --git a/images/etl-round.png b/images/etl-round.png new file mode 100644 index 00000000..f59aba46 Binary files /dev/null and b/images/etl-round.png differ diff --git a/images/etl.pspimage b/images/etl.pspimage deleted file mode 100644 index a5329e63..00000000 Binary files a/images/etl.pspimage and /dev/null differ diff --git a/images/etl64.png b/images/etl64.png new file mode 100644 index 00000000..9a16bbce Binary files /dev/null and b/images/etl64.png differ diff --git a/etl32.png b/images/favicon-32.png similarity index 100% rename from etl32.png rename to images/favicon-32.png diff --git a/images/favicon-64.png b/images/favicon-64.png new file mode 100644 index 00000000..9a16bbce Binary files /dev/null and b/images/favicon-64.png differ diff --git a/include/etl/absolute.h b/include/etl/absolute.h index 165dba9c..d473b3ec 100644 --- a/include/etl/absolute.h +++ b/include/etl/absolute.h @@ -39,7 +39,7 @@ namespace etl // For signed types. //*************************************************************************** template - typename etl::enable_if::value, T>::type + ETL_CONSTEXPR typename etl::enable_if::value, T>::type absolute(T value) { return (value < T(0)) ? -value : value; @@ -49,7 +49,7 @@ namespace etl // For unsigned types. //*************************************************************************** template - typename etl::enable_if::value, T>::type + ETL_CONSTEXPR typename etl::enable_if::value, T>::type absolute(T value) { return value; diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index 534ef9dc..f15ebd7f 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -46,13 +46,15 @@ SOFTWARE. #include "functional.h" #include "utility.h" -#if !defined(ETL_NO_STL) +#if ETL_USING_STL #include #include #include #include #endif +#include "private/minmax_push.h" + namespace etl { // Declare prototypes of the ETL's sort functions @@ -74,7 +76,7 @@ namespace etl //***************************************************************************** namespace etl { -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // iter_swap template @@ -93,7 +95,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // swap_ranges template @@ -120,14 +122,14 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // copy // Pointer template typename etl::enable_if::value && etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy(TIterator1 sb, TIterator1 se, TIterator2 db) { typedef typename etl::iterator_traits::value_type value_t; @@ -142,7 +144,7 @@ namespace etl template typename etl::enable_if::value || !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy(TIterator1 sb, TIterator1 se, TIterator2 db) { while (sb != se) @@ -162,7 +164,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // reverse_copy template @@ -185,14 +187,14 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** // copy_n // Pointer template typename etl::enable_if::value && - etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_pointer::value && + etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy_n(TIterator1 sb, TSize count, TIterator2 db) { typedef typename etl::iterator_traits::value_type value_t; @@ -203,8 +205,8 @@ namespace etl // Other iterator template typename etl::enable_if::value || - !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_pointer::value || + !etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy_n(TIterator1 sb, TSize count, TIterator2 db) { while (count != 0) @@ -230,14 +232,14 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // copy_backward // Pointer template typename etl::enable_if::value && - etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_pointer::value && + etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de) { typedef typename etl::iterator_traits::value_type value_t; @@ -250,8 +252,8 @@ namespace etl // Other iterator template typename etl::enable_if::value || - !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_pointer::value || + !etl::is_trivially_copyable::value_type>::value, TIterator2>::type copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de) { while (se != sb) @@ -272,11 +274,15 @@ namespace etl #endif #if ETL_CPP11_SUPPORTED -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // move + // non-pointer or not trivially copyable template - TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db) + typename etl::enable_if::value || + !etl::is_pointer::value || + !etl::is_trivially_copyable::value_type>::value, TIterator2>::type + move(TIterator1 sb, TIterator1 se, TIterator2 db) { while (sb != se) { @@ -285,6 +291,21 @@ namespace etl return db; } + + // pointer and trivially copyable + template + typename etl::enable_if::value && + etl::is_pointer::value && + etl::is_trivially_copyable::value_type>::value, TIterator2>::type + move(TIterator1 sb, TIterator1 se, TIterator2 db) + { + typedef typename etl::iterator_traits::value_type value_t; + typedef typename etl::iterator_traits::difference_type difference_t; + + difference_t count = (se - sb); + + return TIterator2(memmove(db, sb, sizeof(value_t) * count)) + count; + } #else //*************************************************************************** // move @@ -307,11 +328,15 @@ namespace etl #endif #if ETL_CPP11_SUPPORTED -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // move_backward + // non-pointer, non-pod template - TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de) + typename etl::enable_if::value || + !etl::is_pointer::value || + !etl::is_trivially_copyable::value_type>::value, TIterator2>::type + move_backward(TIterator1 sb, TIterator1 se, TIterator2 de) { while (sb != se) { @@ -320,6 +345,22 @@ namespace etl return de; } + + // pointer and pod + template + typename etl::enable_if::value && + etl::is_pointer::value && + etl::is_trivially_copyable::value_type>::value, TIterator2>::type + move_backward(TIterator1 sb, TIterator1 se, TIterator2 de) + { + typedef typename etl::iterator_traits::value_type value_t; + typedef typename etl::iterator_traits::difference_type difference_t; + + difference_t count = (se - sb); + TIterator2 db = de - count; + + return TIterator2(memmove(db, sb, sizeof(value_t) * count)) + count; + } #else //*************************************************************************** // move_backward @@ -340,7 +381,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // reverse // Pointers @@ -378,7 +419,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // lower_bound template @@ -436,7 +477,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // upper_bound template @@ -494,7 +535,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // equal_range template @@ -532,7 +573,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // find_if template @@ -562,7 +603,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // find template @@ -592,7 +633,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // fill template @@ -621,7 +662,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // fill_n template @@ -658,7 +699,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // count template @@ -690,7 +731,7 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // count_if template @@ -722,12 +763,12 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // equal template ETL_NODISCARD - typename etl::enable_if::value || !etl::is_pointer::value || !etl::is_pod::value_type>::value, bool>::type + typename etl::enable_if::value || !etl::is_pointer::value || !etl::is_trivially_copyable::value_type>::value, bool>::type equal(TIterator1 first1, TIterator1 last1, TIterator2 first2) { while (first1 != last1) @@ -743,13 +784,22 @@ namespace etl template ETL_NODISCARD - typename etl::enable_if::value && etl::is_pointer::value && etl::is_pod::value_type>::value, bool>::type + typename etl::enable_if::value && etl::is_pointer::value && etl::is_trivially_copyable::value_type>::value, bool>::type equal(TIterator1 first1, TIterator1 last1, TIterator2 first2) { typedef typename etl::iterator_traits::value_type value_t; return (memcmp(first1, first2, sizeof(value_t) * (last1 - first1)) == 0); } + + template + ETL_NODISCARD + bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2) + { + return (etl::distance(first1, last1) == etl::distance(first2, last2)) && + etl::equal(first1, last1, first2); + } + #else //*************************************************************************** // equal @@ -759,9 +809,26 @@ namespace etl { return std::equal(first1, last1, first2); } + +#if ETL_CPP14_SUPPORTED + template + ETL_NODISCARD + bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2) + { + return std::equal(first1, last1, first2, last2); + } +#else + template + ETL_NODISCARD + bool equal(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2) + { + return (etl::distance(first1, last1) == etl::distance(first2, last2)) && + etl::equal(first1, last1, first2); + } +#endif #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // lexicographical_compare template @@ -823,7 +890,7 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // min template @@ -859,7 +926,7 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // max template @@ -895,7 +962,30 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL + //*************************************************************************** + // for_each + template + ETL_CONSTEXPR14 TUnaryOperation for_each(TIterator first, TIterator last, TUnaryOperation unary_operation) + { + while (first != last) + { + unary_operation(*first++); + } + + return unary_operation; + } +#else + //*************************************************************************** + // for_each + template + ETL_CONSTEXPR14 TUnaryOperation for_each(TIterator first, TIterator last, TUnaryOperation unary_operation) + { + return std::for_each(first, last, unary_operation); + } +#endif + +#if ETL_NOT_USING_STL //*************************************************************************** // transform template @@ -935,6 +1025,56 @@ namespace etl } #endif +#if ETL_NOT_USING_STL + //*************************************************************************** + // replace + template + ETL_CONSTEXPR14 void replace(TIterator first, TIterator last, const T& old_value, const T& new_value) + { + while (first != last) + { + if (*first == old_value) + { + *first = new_value; + } + + ++first; + } + } + + //*************************************************************************** + // replace_if + template + ETL_CONSTEXPR14 void replace_if(TIterator first, TIterator last, TPredicate predicate, const T& new_value) + { + while (first != last) + { + if (predicate(*first)) + { + *first = new_value; + } + + ++first; + } + } +#else + //*************************************************************************** + // replace + template + ETL_CONSTEXPR14 void replace(TIterator first, TIterator last, const T& old_value, const T& new_value) + { + std::replace(first, last, old_value, new_value); + } + + //*************************************************************************** + // replace_if + template + ETL_CONSTEXPR14 void replace_if(TIterator first, TIterator last, TPredicate predicate, const T& new_value) + { + std::replace_if(first, last, predicate, new_value); + } +#endif + //*************************************************************************** // Heap namespace private_heap @@ -1006,7 +1146,7 @@ namespace etl } } - #if defined (ETL_NO_STL) + #if ETL_NOT_USING_STL // Pop Heap template void pop_heap(TIterator first, TIterator last, TCompare compare) @@ -1186,7 +1326,7 @@ namespace etl { #if ETL_CPP11_SUPPORTED return std::is_heap(first, last); -#else +#else typedef etl::less::value_type> compare; return private_heap::is_heap(first, last - first, compare()); #endif @@ -1208,7 +1348,7 @@ namespace etl #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // Search template @@ -1273,33 +1413,91 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // Rotate + namespace private_algorithm + { + //********************************* + template + TIterator rotate_general(TIterator first, TIterator middle, TIterator last) + { + TIterator next = middle; + + while (first != next) + { + using ETL_OR_STD::swap; // Allow ADL + + swap(*first++, *next++); + + if (next == last) + { + next = middle; + } + else if (first == middle) + { + middle = next; + } + } + + return first; + } + + //********************************* + template + TIterator rotate_left_by_one(TIterator first, TIterator last) + { + typedef typename etl::iterator_traits::value_type value_type; + + // Save the first item. + value_type temp(etl::move(*first)); + + // Move the rest. + TIterator result = etl::move(etl::next(first), last, first); + + // Restore the first item in its rotated position. + *result = etl::move(temp); + + // The new position of the first item. + return result; + } + + //********************************* + template + TIterator rotate_right_by_one(TIterator first, TIterator last) + { + typedef typename etl::iterator_traits::value_type value_type; + + // Save the last item. + TIterator previous = etl::prev(last); + value_type temp(etl::move(*previous)); + + // Move the rest. + TIterator result = etl::move_backward(first, previous, last); + + // Restore the last item in its rotated position. + *first = etl::move(temp); + + // The new position of the first item. + return result; + } + } + + //********************************* template TIterator rotate(TIterator first, TIterator middle, TIterator last) { - using ETL_OR_STD::swap; // Allow ADL - - TIterator next = middle; - - while (first != next) + if (etl::next(first) == middle) { - using ETL_OR_STD::swap; - - swap(*first++, *next++); - - if (next == last) - { - next = middle; - } - else if (first == middle) - { - middle = next; - } + return private_algorithm::rotate_left_by_one(first, last); } - return first; + if (etl::next(middle) == last) + { + return private_algorithm::rotate_right_by_one(first, last); + } + + return private_algorithm::rotate_general(first, middle, last); } #else //*************************************************************************** @@ -1311,7 +1509,7 @@ namespace etl } #endif -#if defined (ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** // find_end // Predicate @@ -1379,7 +1577,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** /// Finds the iterator to the smallest element in the range (begin, end).
/// @@ -1449,7 +1647,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** /// Finds the iterator to the largest element in the range (begin, end).
/// @@ -1519,7 +1717,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// Finds the greatest and the smallest element in the range (begin, end).
/// @@ -1595,7 +1793,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// minmax ///\ingroup algorithm @@ -1651,7 +1849,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// is_sorted_until ///\ingroup algorithm @@ -1737,7 +1935,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// is_sorted ///\ingroup algorithm @@ -1793,7 +1991,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// find_if_not ///\ingroup algorithm @@ -1833,7 +2031,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// is_permutation ///\ingroup algorithm @@ -2029,7 +2227,7 @@ namespace etl #endif #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// is_partitioned ///\ingroup algorithm @@ -2075,7 +2273,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// partition_point /// @@ -2115,7 +2313,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// Copies the elements from the range (begin, end) to two different ranges /// depending on the value returned by the predicate.
@@ -2161,7 +2359,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// copy_if ///\ingroup algorithm @@ -2201,7 +2399,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// all_of ///\ingroup algorithm @@ -2231,7 +2429,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// any_of ///\ingroup algorithm @@ -2261,7 +2459,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) || !ETL_CPP11_SUPPORTED +#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED //*************************************************************************** /// none_of ///\ingroup algorithm @@ -2291,7 +2489,7 @@ namespace etl } #endif -#if defined(ETL_NO_STL) +#if ETL_NOT_USING_STL //*************************************************************************** /// Sorts the elements. /// Uses user defined comparison. @@ -3244,4 +3442,6 @@ namespace etl #endif } +#include "private/minmax_pop.h" + #endif diff --git a/include/etl/alignment.h b/include/etl/alignment.h index 5ebabba5..8b299f39 100644 --- a/include/etl/alignment.h +++ b/include/etl/alignment.h @@ -99,7 +99,7 @@ namespace etl { public: -#if defined(ETL_NO_64BIT_TYPES) +#if ETL_NOT_USING_64BIT_TYPES typedef typename private_alignment::type_with_alignment_helper::type type; #else typedef typename private_alignment::type_with_alignment_helper::type type; @@ -184,7 +184,7 @@ namespace etl return reinterpret_cast(data); } -#if ETL_CPP11_SUPPORTED +#if ETL_CPP11_SUPPORTED && !defined(ETL_COMPILER_ARM5) alignas(ALIGNMENT) char data[LENGTH]; #else union @@ -196,14 +196,24 @@ namespace etl }; }; +#if ETL_CPP11_SUPPORTED + template + using aligned_storage_t = typename aligned_storage::type; +#endif + //*************************************************************************** /// Aligned storage as ///\ingroup alignment //*************************************************************************** - template + template struct aligned_storage_as : public etl::aligned_storage::value> { }; + +#if ETL_CPP11_SUPPORTED + template + using aligned_storage_as_t = typename aligned_storage_as::type; +#endif } #endif diff --git a/include/etl/array.h b/include/etl/array.h index 6bc922ef..e48f83b1 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -5,7 +5,7 @@ The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl -http://www.etlcpp.com +https://www.etlcpp.com Copyright(c) 2014 jwellbelove @@ -139,7 +139,7 @@ namespace etl /// Returns a reference to the value at index 'i'. ///\param i The index of the element to access. //************************************************************************* - reference operator[](size_t i) + ETL_CONSTEXPR reference operator[](size_t i) { return _buffer[i]; } @@ -149,7 +149,7 @@ namespace etl /// Returns a const reference to the value at index 'i'. ///\param i The index of the element to access. //************************************************************************* - const_reference operator[](size_t i) const + ETL_CONSTEXPR const_reference operator[](size_t i) const { return _buffer[i]; } @@ -157,7 +157,7 @@ namespace etl //************************************************************************* /// Returns a reference to the first element. //************************************************************************* - reference front() + ETL_CONSTEXPR reference front() { return _buffer[0]; } @@ -165,7 +165,7 @@ namespace etl //************************************************************************* /// Returns a const reference to the first element. //************************************************************************* - const_reference front() const + ETL_CONSTEXPR const_reference front() const { return _buffer[0]; } @@ -173,7 +173,7 @@ namespace etl //************************************************************************* /// Returns a reference to the last element. //************************************************************************* - reference back() + ETL_CONSTEXPR reference back() { return _buffer[SIZE - 1]; } @@ -181,7 +181,7 @@ namespace etl //************************************************************************* /// Returns a const reference to the last element. //************************************************************************* - const_reference back() const + ETL_CONSTEXPR const_reference back() const { return _buffer[SIZE - 1]; } @@ -189,7 +189,7 @@ namespace etl //************************************************************************* /// Returns a pointer to the first element of the internal buffer. //************************************************************************* - pointer data() + ETL_CONSTEXPR pointer data() ETL_NOEXCEPT { return &_buffer[0]; } @@ -197,7 +197,7 @@ namespace etl //************************************************************************* /// Returns a const pointer to the first element of the internal buffer. //************************************************************************* - const_pointer data() const + ETL_CONSTEXPR const_pointer data() const ETL_NOEXCEPT { return &_buffer[0]; } @@ -209,7 +209,7 @@ namespace etl //************************************************************************* /// Returns an iterator to the beginning of the array. //************************************************************************* - iterator begin() + ETL_CONSTEXPR iterator begin() ETL_NOEXCEPT { return &_buffer[0]; } @@ -217,7 +217,7 @@ namespace etl //************************************************************************* /// Returns a const iterator to the beginning of the array. //************************************************************************* - const_iterator begin() const + ETL_CONSTEXPR const_iterator begin() const ETL_NOEXCEPT { return &_buffer[0]; } @@ -225,7 +225,7 @@ namespace etl //************************************************************************* /// Returns a const iterator to the beginning of the array. //************************************************************************* - const_iterator cbegin() const + ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT { return begin(); } @@ -233,7 +233,7 @@ namespace etl //************************************************************************* /// Returns an iterator to the end of the array. //************************************************************************* - iterator end() + ETL_CONSTEXPR iterator end() ETL_NOEXCEPT { return &_buffer[SIZE]; } @@ -241,7 +241,7 @@ namespace etl //************************************************************************* /// Returns a const iterator to the end of the array. //************************************************************************* - const_iterator end() const + ETL_CONSTEXPR const_iterator end() const ETL_NOEXCEPT { return &_buffer[SIZE]; } @@ -249,7 +249,7 @@ namespace etl //************************************************************************* // Returns a const iterator to the end of the array. //************************************************************************* - const_iterator cend() const + ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT { return &_buffer[SIZE]; } @@ -257,7 +257,7 @@ namespace etl //************************************************************************* // Returns an reverse iterator to the reverse beginning of the array. //************************************************************************* - reverse_iterator rbegin() + ETL_CONSTEXPR reverse_iterator rbegin() ETL_NOEXCEPT { return reverse_iterator(end()); } @@ -265,7 +265,7 @@ namespace etl //************************************************************************* /// Returns a const reverse iterator to the reverse beginning of the array. //************************************************************************* - const_reverse_iterator rbegin() const + ETL_CONSTEXPR const_reverse_iterator rbegin() const ETL_NOEXCEPT { return const_reverse_iterator(end()); } @@ -273,7 +273,7 @@ namespace etl //************************************************************************* /// Returns a const reverse iterator to the reverse beginning of the array. //************************************************************************* - const_reverse_iterator crbegin() const + ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT { return const_reverse_iterator(end()); } @@ -281,7 +281,7 @@ namespace etl //************************************************************************* /// Returns a reverse iterator to the end of the array. //************************************************************************* - reverse_iterator rend() + ETL_CONSTEXPR reverse_iterator rend() ETL_NOEXCEPT { return reverse_iterator(begin()); } @@ -289,7 +289,7 @@ namespace etl //************************************************************************* /// Returns a const reverse iterator to the end of the array. //************************************************************************* - const_reverse_iterator rend() const + ETL_CONSTEXPR const_reverse_iterator rend() const ETL_NOEXCEPT { return const_reverse_iterator(begin()); } @@ -297,7 +297,7 @@ namespace etl //************************************************************************* /// Returns a const reverse iterator to the end of the array. //************************************************************************* - const_reverse_iterator crend() const + ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT { return const_reverse_iterator(begin()); } @@ -309,7 +309,7 @@ namespace etl //************************************************************************* /// Returns true if the array size is zero. //************************************************************************* - bool empty() const + ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT { return (SIZE == 0); } @@ -317,7 +317,7 @@ namespace etl //************************************************************************* /// Returns the size of the array. //************************************************************************* - size_t size() const + ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT { return SIZE; } @@ -325,7 +325,7 @@ namespace etl //************************************************************************* /// Returns the maximum possible size of the array. //************************************************************************* - size_t max_size() const + ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT { return SIZE; } @@ -347,7 +347,7 @@ namespace etl /// Swaps the contents of this array and another. ///\param other A reference to the other array. //************************************************************************* - void swap(array& other) + void swap(array& other) ETL_NOEXCEPT { using ETL_OR_STD::swap; // Allow ADL @@ -552,6 +552,15 @@ namespace etl T _buffer[SIZE]; }; + //************************************************************************* + /// Template deduction guides. + //************************************************************************* +#if ETL_CPP17_SUPPORTED + template + array(T, Ts...) + -> array && ...), T>, 1U + sizeof...(Ts)>; +#endif + //************************************************************************* /// Overloaded swap for etl::array ///\param lhs The first array. @@ -670,4 +679,3 @@ namespace etl } #endif - diff --git a/include/etl/array_view.h b/include/etl/array_view.h index a682b665..c74331ee 100644 --- a/include/etl/array_view.h +++ b/include/etl/array_view.h @@ -39,16 +39,13 @@ SOFTWARE. #include "nullptr.h" #include "hash.h" #include "algorithm.h" - -#include "algorithm.h" +#include "memory.h" +#include "type_traits.h" ///\defgroup array array /// A wrapper for arrays ///\ingroup containers -#undef ETL_FILE -#define ETL_FILE "41" - namespace etl { //*************************************************************************** @@ -73,7 +70,7 @@ namespace etl public: array_view_bounds(string_type file_name_, numeric_type line_number_) - : array_view_exception(ETL_ERROR_TEXT("array_view:bounds", ETL_FILE"A"), file_name_, line_number_) + : array_view_exception(ETL_ERROR_TEXT("array_view:bounds", ETL_ARRAY_VIEW_FILE_ID"A"), file_name_, line_number_) { } }; @@ -87,7 +84,7 @@ namespace etl public: array_view_uninitialised(string_type file_name_, numeric_type line_number_) - : array_view_exception(ETL_ERROR_TEXT("array_view:uninitialised", ETL_FILE"B"), file_name_, line_number_) + : array_view_exception(ETL_ERROR_TEXT("array_view:uninitialised", ETL_ARRAY_VIEW_FILE_ID"B"), file_name_, line_number_) { } }; @@ -100,23 +97,31 @@ namespace etl { public: - typedef T value_type; - typedef size_t size_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef T* iterator; - typedef const T* const_iterator; - typedef ETL_OR_STD::reverse_iterator reverse_iterator; + typedef T value_type; + typedef size_t size_type; + typedef const T& const_reference; + typedef const T* const_pointer; + typedef const T* const_iterator; typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; +#if defined(ETL_ARRAY_VIEW_IS_MUTABLE) + typedef T* pointer; + typedef T& reference; + typedef T* iterator; + typedef ETL_OR_STD::reverse_iterator reverse_iterator; +#else + typedef const_pointer pointer; + typedef const_reference reference; + typedef const_pointer iterator; + typedef const_reverse_iterator reverse_iterator; +#endif + //************************************************************************* /// Default constructor. //************************************************************************* ETL_CONSTEXPR array_view() - : mbegin(nullptr), - mend(nullptr) + : mbegin(ETL_NULLPTR), + mend(ETL_NULLPTR) { } @@ -125,7 +130,7 @@ namespace etl /// data() and size() member functions. //************************************************************************* template - ETL_CONSTEXPR explicit array_view(TArray& a) + ETL_CONSTEXPR array_view(TArray& a) : mbegin(a.data()), mend(a.data() + a.size()) { @@ -155,8 +160,8 @@ namespace etl //************************************************************************* /// Construct from C array //************************************************************************* - template - ETL_CONSTEXPR explicit array_view(T(&begin_)[ARRAY_SIZE]) + template + ETL_CONSTEXPR array_view(T(&begin_)[ARRAY_SIZE]) : mbegin(begin_), mend(begin_ + ARRAY_SIZE) { @@ -370,6 +375,7 @@ namespace etl mend = etl::addressof(*begin_) + size_; } +#if defined(ETL_ARRAY_VIEW_IS_MUTABLE) //************************************************************************* /// Returns a reference to the indexed value. //************************************************************************* @@ -377,6 +383,7 @@ namespace etl { return mbegin[i]; } +#endif //************************************************************************* /// Returns a const reference to the indexed value. @@ -386,22 +393,24 @@ namespace etl return mbegin[i]; } +#if defined(ETL_ARRAY_VIEW_IS_MUTABLE) //************************************************************************* /// Returns a reference to the indexed value. //************************************************************************* reference at(const size_t i) { - ETL_ASSERT((mbegin != nullptr && mend != nullptr), ETL_ERROR(array_view_uninitialised)); + ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised)); ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds)); return mbegin[i]; } +#endif //************************************************************************* /// Returns a const reference to the indexed value. //************************************************************************* const_reference at(const size_t i) const { - ETL_ASSERT((mbegin != nullptr && mend != nullptr), ETL_ERROR(array_view_uninitialised)); + ETL_ASSERT((mbegin != ETL_NULLPTR && mend != ETL_NULLPTR), ETL_ERROR(array_view_uninitialised)); ETL_ASSERT(i < size(), ETL_ERROR(array_view_bounds)); return mbegin[i]; } @@ -422,7 +431,10 @@ namespace etl //************************************************************************* void remove_prefix(const size_type n) { - mbegin += n; + if (n < size()) + mbegin += n; + else + mbegin = mend; } //************************************************************************* @@ -430,7 +442,10 @@ namespace etl //************************************************************************* void remove_suffix(const size_type n) { - mend -= n; + if (n < size()) + mend -= n; + else + mend = mbegin; } //************************************************************************* @@ -484,10 +499,28 @@ namespace etl private: - T* mbegin; - T* mend; + pointer mbegin; + pointer mend; }; + //************************************************************************* + /// Template deduction guides. + //************************************************************************* +#if ETL_CPP17_SUPPORTED + template + array_view(TArray& a) + -> array_view; + + template + array_view(const TIterator begin_, const TIterator end_) + -> array_view>; + + template + array_view(const TIterator begin_, const TSize size_) + -> array_view>; +#endif + //************************************************************************* /// Hash function. //************************************************************************* @@ -513,7 +546,4 @@ void swap(etl::array_view& lhs, etl::array_view& rhs) lhs.swap(rhs); } -#undef ETL_FILE - #endif - diff --git a/include/etl/array_wrapper.h b/include/etl/array_wrapper.h index cf72edb2..c486b764 100644 --- a/include/etl/array_wrapper.h +++ b/include/etl/array_wrapper.h @@ -45,9 +45,6 @@ SOFTWARE. /// A wrapper for arrays ///\ingroup containers -#undef ETL_FILE -#define ETL_FILE "42" - namespace etl { //*************************************************************************** @@ -72,7 +69,7 @@ namespace etl public: array_wrapper_bounds(string_type file_name_, numeric_type line_number_) - : array_wrapper_exception(ETL_ERROR_TEXT("array_wrapper:bounds", ETL_FILE"A"), file_name_, line_number_) + : array_wrapper_exception(ETL_ERROR_TEXT("array_wrapper:bounds", ETL_ARRAY_WRAPPER_FILE_ID"A"), file_name_, line_number_) { } }; @@ -417,7 +414,5 @@ void swap(etl::array_wrapper& lhs, #define ETL_ARRAY_WRAPPER(arraytype, arrayobject) etl::array_wrapper -#undef ETL_FILE - #endif diff --git a/include/etl/atomic.h b/include/etl/atomic.h index 41996c07..1af2a01b 100644 --- a/include/etl/atomic.h +++ b/include/etl/atomic.h @@ -31,7 +31,7 @@ SOFTWARE. #include "platform.h" -#if ETL_CPP11_SUPPORTED == 1 && !defined(ETL_NO_STL) +#if ETL_CPP11_SUPPORTED && (ETL_USING_STL || defined(ETL_IN_UNIT_TEST)) #include "atomic/atomic_std.h" #define ETL_HAS_ATOMIC 1 #elif defined(ETL_COMPILER_ARM5) @@ -43,8 +43,12 @@ SOFTWARE. #elif defined(ETL_COMPILER_GCC) #include "atomic/atomic_gcc_sync.h" #define ETL_HAS_ATOMIC 1 +#elif defined(ETL_COMPILER_CLANG) + #include "atomic/atomic_clang_sync.h" + #define ETL_HAS_ATOMIC 1 #else #define ETL_HAS_ATOMIC 0 + #pragma message ("ETL atomics not supported") #endif #endif diff --git a/include/etl/atomic/atomic_clang_sync.h b/include/etl/atomic/atomic_clang_sync.h new file mode 100644 index 00000000..d4a3c930 --- /dev/null +++ b/include/etl/atomic/atomic_clang_sync.h @@ -0,0 +1,34 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2017 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_ATOMIC_CLANG_INCLUDED +#define ETL_ATOMIC_CLANG_INCLUDED + +#include "atomic_gcc_sync.h" + +#endif \ No newline at end of file diff --git a/include/etl/atomic/atomic_gcc_sync.h b/include/etl/atomic/atomic_gcc_sync.h index da86e89e..be188655 100644 --- a/include/etl/atomic/atomic_gcc_sync.h +++ b/include/etl/atomic/atomic_gcc_sync.h @@ -61,6 +61,9 @@ namespace etl memory_order_seq_cst } memory_order; + //*************************************************************************** + /// For all types except bool and pointers + //*************************************************************************** template class atomic { @@ -430,24 +433,27 @@ namespace etl private: - atomic& operator =(const atomic&); - atomic& operator =(const atomic&) volatile; + atomic& operator =(const atomic&) ETL_DELETE; + atomic& operator =(const atomic&) volatile ETL_DELETE; mutable volatile T value; }; + //*************************************************************************** + /// Specialisation for pointers + //*************************************************************************** template class atomic { public: atomic() - : value(nullptr) + : value(0U) { } atomic(T* v) - : value(v) + : value(uintptr_t(v)) { } @@ -540,7 +546,7 @@ namespace etl operator T*() volatile const { - return __sync_fetch_and_add(&value, 0); + return (T*)__sync_fetch_and_add(&value, 0); } // Is lock free? @@ -557,12 +563,12 @@ namespace etl // Store void store(T* v, etl::memory_order order = etl::memory_order_seq_cst) { - __sync_lock_test_and_set(&value, v); + __sync_lock_test_and_set(&value, uintptr_t(v)); } void store(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - __sync_lock_test_and_set(&value, v); + __sync_lock_test_and_set(&value, uintptr_t(v)); } // Load @@ -573,7 +579,7 @@ namespace etl T* load(etl::memory_order order = etl::memory_order_seq_cst) const volatile { - return __sync_fetch_and_add(&value, 0); + return (T*)__sync_fetch_and_add(&value, 0); } // Fetch add @@ -601,18 +607,18 @@ namespace etl // Exchange T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) { - return (T*)__sync_lock_test_and_set(&value, v); + return (T*)__sync_lock_test_and_set(&value, uintptr_t(v)); } T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile { - return (T*)__sync_lock_test_and_set(&value, v); + return (T*)__sync_lock_test_and_set(&value, uintptr_t(v)); } // Compare exchange weak bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) { - T* old = __sync_val_compare_and_swap(&value, expected, desired); + T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)); if (old == expected) { @@ -627,7 +633,7 @@ namespace etl bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) volatile { - T* old = __sync_val_compare_and_swap(&value, expected, desired); + T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)); if (old == expected) { @@ -642,7 +648,7 @@ namespace etl bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) { - T* old = __sync_val_compare_and_swap(&value, expected, desired); + T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)); if (old == expected) { @@ -657,7 +663,7 @@ namespace etl bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) volatile { - T* old = __sync_val_compare_and_swap(&value, expected, desired); + T* old = (T*)__sync_val_compare_and_swap(&value, uintptr_t(expected), uintptr_t(desired)); if (old == expected) { @@ -737,10 +743,10 @@ namespace etl private: - atomic& operator =(const atomic&); - atomic& operator =(const atomic&) volatile; + atomic& operator =(const atomic&) ETL_DELETE; + atomic& operator =(const atomic&) volatile ETL_DELETE; - mutable volatile T* value; + mutable uintptr_t value; }; typedef etl::atomic atomic_char; @@ -757,13 +763,15 @@ namespace etl typedef etl::atomic atomic_wchar_t; typedef etl::atomic atomic_char16_t; typedef etl::atomic atomic_char32_t; +#if ETL_USING_8BIT_TYPES typedef etl::atomic atomic_uint8_t; typedef etl::atomic atomic_int8_t; +#endif typedef etl::atomic atomic_uint16_t; typedef etl::atomic atomic_int16_t; typedef etl::atomic atomic_uint32_t; typedef etl::atomic atomic_int32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef etl::atomic atomic_uint64_t; typedef etl::atomic atomic_int64_t; #endif @@ -773,7 +781,7 @@ namespace etl typedef etl::atomic atomic_uint_least16_t; typedef etl::atomic atomic_int_least32_t; typedef etl::atomic atomic_uint_least32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef etl::atomic atomic_int_least64_t; typedef etl::atomic atomic_uint_least64_t; #endif @@ -783,7 +791,7 @@ namespace etl typedef etl::atomic atomic_uint_fast16_t; typedef etl::atomic atomic_int_fast32_t; typedef etl::atomic atomic_uint_fast32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef etl::atomic atomic_int_fast64_t; typedef etl::atomic atomic_uint_fast64_t; #endif diff --git a/include/etl/atomic/atomic_llvm_sync.h b/include/etl/atomic/atomic_llvm_sync.h deleted file mode 100644 index 50e0be01..00000000 --- a/include/etl/atomic/atomic_llvm_sync.h +++ /dev/null @@ -1,785 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 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_ATOMIC_LLVM_SYNC_INCLUDED -#define ETL_ATOMIC_LLVM_SYNC_INCLUDED - -//#include "../platform.h" -//#include "../type_traits.h" -//#include "../static_assert.h" -//#include "../nullptr.h" -//#include "../char_traits.h" -// -//#include -// -//namespace etl -//{ -// //*************************************************************************** -// // Atomic type for pre C++11 GCC compilers that support the builtin '__sync' functions. -// // Only integral and pointer types are supported. -// //*************************************************************************** -// -// typedef enum memory_order -// { -// memory_order_relaxed, -// memory_order_consume, -// memory_order_acquire, -// memory_order_release, -// memory_order_acq_rel, -// memory_order_seq_cst -// } memory_order; -// -// template -// class atomic -// { -// public: -// -// ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); -// -// atomic() -// : value(0) -// { -// } -// -// atomic(T v) -// : value(v) -// { -// } -// -// // Assignment -// T operator =(T v) -// { -// store(v); -// -// return v; -// } -// -// T operator =(T v) volatile -// { -// store(v); -// -// return v; -// } -// -// // Pre-increment -// T operator ++() -// { -// return fetch_add(1) + 1; -// } -// -// T operator ++() volatile -// { -// return fetch_add(1) + 1; -// } -// -// // Post-increment -// T operator ++(int) -// { -// return fetch_add(1); -// } -// -// T operator ++(int) volatile -// { -// return fetch_add(1); -// } -// -// // Pre-decrement -// T operator --() -// { -// return fetch_sub(1) + 1; -// } -// -// T operator --() volatile -// { -// return fetch_sub(1) + 1; -// } -// -// // Post-decrement -// T operator --(int) -// { -// return fetch_sub(1); -// } -// -// T operator --(int) volatile -// { -// return fetch_sub(1); -// } -// -// // Add -// T operator +=(T v) -// { -// return fetch_add(v) + v; -// } -// -// T operator +=(T v) volatile -// { -// return fetch_add(v) + v; -// } -// -// // Subtract -// T operator -=(T v) -// { -// return fetch_sub(v) - v; -// } -// -// T operator -=(T v) volatile -// { -// return fetch_sub(v) - v; -// } -// -// // And -// T operator &=(T v) -// { -// return fetch_and(v) & v; -// } -// -// T operator &=(T v) volatile -// { -// return fetch_and(v) & v; -// } -// -// // Or -// T operator |=(T v) -// { -// return fetch_or(v) | v; -// } -// -// T operator |=(T v) volatile -// { -// return fetch_or(v) | v; -// } -// -// // Exclusive or -// T operator ^=(T v) -// { -// return fetch_xor(v) ^ v; -// } -// -// T operator ^=(T v) volatile -// { -// return fetch_xor(v) ^ v; -// } -// -// // Conversion operator -// operator T () const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// operator T() volatile const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// // Is lock free? -// bool is_lock_free() const -// { -// return true; -// } -// -// bool is_lock_free() const volatile -// { -// return true; -// } -// -// // Store -// void store(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// __sync_lock_test_and_set(&value, v); -// } -// -// void store(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// __sync_lock_test_and_set(&value, v); -// } -// -// // Load -// T load(etl::memory_order order = etl::memory_order_seq_cst) const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// T load(etl::memory_order order = etl::memory_order_seq_cst) const volatile -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// // Fetch add -// T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_add(&value, v); -// } -// -// T fetch_add(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_add(&value, v); -// } -// -// // Fetch subtract -// T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_sub(&value, v); -// } -// -// T fetch_sub(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_sub(&value, v); -// } -// -// // Fetch or -// T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_or(&value, v); -// } -// -// T fetch_or(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_or(&value, v); -// } -// -// // Fetch and -// T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_and(&value, v); -// } -// -// T fetch_and(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_and(&value, v); -// } -// -// // Fetch exclusive or -// T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_xor(&value, v); -// } -// -// T fetch_xor(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_xor(&value, v); -// } -// -// // Exchange -// T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_lock_test_and_set(&value, v); -// } -// -// T exchange(T v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_lock_test_and_set(&value, v); -// } -// -// // Compare exchange weak -// bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) -// { -// T old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// T old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure) -// { -// T old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T& expected, T desired, etl::memory_order success, etl::memory_order failure) volatile -// { -// T old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// // Compare exchange strong -// bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) -// { -// T old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T& expected, T desired, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// T old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure) -// { -// T old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T& expected, T desired, etl::memory_order success, etl::memory_order failure) volatile -// { -// T old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// private: -// -// atomic& operator =(const atomic&); -// atomic& operator =(const atomic&) volatile; -// -// mutable volatile T value; -// }; -// -// template -// class atomic -// { -// public: -// -// atomic() -// : value(nullptr) -// { -// } -// -// atomic(T* v) -// : value(v) -// { -// } -// -// // Assignment -// T* operator =(T* v) -// { -// store(v); -// -// return v; -// } -// -// T* operator =(T* v) volatile -// { -// store(v); -// -// return v; -// } -// -// // Pre-increment -// T* operator ++() -// { -// return fetch_add(1) + 1; -// } -// -// T* operator ++() volatile -// { -// return fetch_add(1) + 1; -// } -// -// // Post-increment -// T* operator ++(int) -// { -// return fetch_add(1); -// } -// -// T* operator ++(int) volatile -// { -// return fetch_add(1); -// } -// -// // Pre-decrement -// T* operator --() -// { -// return fetch_sub(1) + 1; -// } -// -// T* operator --() volatile -// { -// return fetch_sub(1) + 1; -// } -// -// // Post-decrement -// T* operator --(int) -// { -// return fetch_sub(1); -// } -// -// T* operator --(int) volatile -// { -// return fetch_sub(1); -// } -// -// // Add -// T* operator +=(ptrdiff_t v) -// { -// return fetch_add(v) + v; -// } -// -// T* operator +=(ptrdiff_t v) volatile -// { -// return fetch_add(v) + v; -// } -// -// // Subtract -// T* operator -=(ptrdiff_t v) -// { -// return fetch_sub(v) - v; -// } -// -// T* operator -=(ptrdiff_t v) volatile -// { -// return fetch_sub(v) - v; -// } -// -// // Conversion operator -// operator T* () const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// operator T*() volatile const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// // Is lock free? -// bool is_lock_free() const -// { -// return true; -// } -// -// bool is_lock_free() const volatile -// { -// return true; -// } -// -// // Store -// void store(T* v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// __sync_lock_test_and_set(&value, v); -// } -// -// void store(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// __sync_lock_test_and_set(&value, v); -// } -// -// // Load -// T* load(etl::memory_order order = etl::memory_order_seq_cst) const -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// T* load(etl::memory_order order = etl::memory_order_seq_cst) const volatile -// { -// return __sync_fetch_and_add(&value, 0); -// } -// -// // Fetch add -// T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_add(&value, v); -// } -// -// T* fetch_add(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_add(&value, v); -// } -// -// // Fetch subtract -// T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_fetch_and_sub(&value, v); -// } -// -// T* fetch_sub(ptrdiff_t v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_fetch_and_sub(&value, v); -// } -// -// // Exchange -// T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) -// { -// return __sync_lock_test_and_set(&value, v); -// } -// -// T* exchange(T* v, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// return __sync_lock_test_and_set(&value, v); -// } -// -// // Compare exchange weak -// bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) -// { -// T* old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// T* old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) -// { -// T* old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// bool compare_exchange_weak(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) volatile -// { -// T* old = __sync_val_compare_and_swap(&value, expected, desired); -// -// if (old == expected) -// { -// return true; -// } -// else -// { -// expected = old; -// return false; -// } -// } -// -// // Compare exchange strong -// bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) -// { -// T* old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T*))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order order = etl::memory_order_seq_cst) volatile -// { -// T* old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T*))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) -// { -// T* old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T*))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// bool compare_exchange_strong(T*& expected, T* desired, etl::memory_order success, etl::memory_order failure) volatile -// { -// T* old = expected; -// -// while (!compare_exchange_weak(old, desired)) -// { -// if (memcmp(&old, &expected, sizeof(T*))) -// { -// expected = old; -// return false; -// } -// } -// -// return true; -// } -// -// private: -// -// atomic& operator =(const atomic&); -// atomic& operator =(const atomic&) volatile; -// -// mutable volatile T* value; -// }; -// -// typedef etl::atomic atomic_char; -// typedef etl::atomic atomic_schar; -// typedef etl::atomic atomic_uchar; -// typedef etl::atomic atomic_short; -// typedef etl::atomic atomic_ushort; -// typedef etl::atomic atomic_int; -// typedef etl::atomic atomic_uint; -// typedef etl::atomic atomic_long; -// typedef etl::atomic atomic_ulong; -// typedef etl::atomic atomic_llong; -// typedef etl::atomic atomic_ullong; -// typedef etl::atomic atomic_wchar_t; -// typedef etl::atomic atomic_char16_t; -// typedef etl::atomic atomic_char32_t; -// typedef etl::atomic atomic_uint8_t; -// typedef etl::atomic atomic_int8_t; -// typedef etl::atomic atomic_uint16_t; -// typedef etl::atomic atomic_int16_t; -// typedef etl::atomic atomic_uint32_t; -// typedef etl::atomic atomic_int32_t; -// typedef etl::atomic atomic_uint64_t; -// typedef etl::atomic atomic_int64_t; -// typedef etl::atomic atomic_int_least8_t; -// typedef etl::atomic atomic_uint_least8_t; -// typedef etl::atomic atomic_int_least16_t; -// typedef etl::atomic atomic_uint_least16_t; -// typedef etl::atomic atomic_int_least32_t; -// typedef etl::atomic atomic_uint_least32_t; -// typedef etl::atomic atomic_int_least64_t; -// typedef etl::atomic atomic_uint_least64_t; -// typedef etl::atomic atomic_int_fast8_t; -// typedef etl::atomic atomic_uint_fast8_t; -// typedef etl::atomic atomic_int_fast16_t; -// typedef etl::atomic atomic_uint_fast16_t; -// typedef etl::atomic atomic_int_fast32_t; -// typedef etl::atomic atomic_uint_fast32_t; -// typedef etl::atomic atomic_int_fast64_t; -// typedef etl::atomic atomic_uint_fast64_t; -// typedef etl::atomic atomic_intptr_t; -// typedef etl::atomic atomic_uintptr_t; -// typedef etl::atomic atomic_size_t; -// typedef etl::atomic atomic_ptrdiff_t; -// typedef etl::atomic atomic_intmax_t; -// typedef etl::atomic atomic_uintmax_t; -//} - -#endif diff --git a/include/etl/atomic/atomic_std.h b/include/etl/atomic/atomic_std.h index 9c160f71..7dce3647 100644 --- a/include/etl/atomic/atomic_std.h +++ b/include/etl/atomic/atomic_std.h @@ -343,7 +343,7 @@ namespace etl public: atomic() - : value(nullptr) + : value(ETL_NULLPTR) { } @@ -550,12 +550,13 @@ namespace etl private: - atomic & operator =(const atomic&); - //atomic& operator =(const atomic&) volatile; + atomic & operator =(const atomic&) ETL_DELETE; + atomic& operator =(const atomic&) volatile ETL_DELETE; std::atomic value; }; + typedef std::atomic atomic_bool; typedef std::atomic atomic_char; typedef std::atomic atomic_schar; typedef std::atomic atomic_uchar; @@ -570,13 +571,15 @@ namespace etl typedef std::atomic atomic_wchar_t; typedef std::atomic atomic_char16_t; typedef std::atomic atomic_char32_t; +#if ETL_USING_8BIT_TYPES typedef std::atomic atomic_uint8_t; typedef std::atomic atomic_int8_t; +#endif typedef std::atomic atomic_uint16_t; typedef std::atomic atomic_int16_t; typedef std::atomic atomic_uint32_t; typedef std::atomic atomic_int32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef std::atomic atomic_uint64_t; typedef std::atomic atomic_int64_t; #endif @@ -586,7 +589,7 @@ namespace etl typedef std::atomic atomic_uint_least16_t; typedef std::atomic atomic_int_least32_t; typedef std::atomic atomic_uint_least32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef std::atomic atomic_int_least64_t; typedef std::atomic atomic_uint_least64_t; #endif @@ -596,7 +599,7 @@ namespace etl typedef std::atomic atomic_uint_fast16_t; typedef std::atomic atomic_int_fast32_t; typedef std::atomic atomic_uint_fast32_t; -#if !defined(ETL_NO_64BIT_TYPES) +#if ETL_USING_64BIT_TYPES typedef std::atomic atomic_int_fast64_t; typedef std::atomic atomic_uint_fast64_t; #endif diff --git a/include/etl/basic_format_spec.h b/include/etl/basic_format_spec.h index ca3da502..43cfe805 100644 --- a/include/etl/basic_format_spec.h +++ b/include/etl/basic_format_spec.h @@ -39,6 +39,165 @@ SOFTWARE. namespace etl { + namespace private_basic_format_spec + { + //******************************************************* + // Structures returned by stream formatting manipulators. + //******************************************************* + struct base_spec + { + ETL_CONSTEXPR base_spec(uint_least8_t base_) + : base(base_) + { + } + + const uint_least8_t base; + }; + + //********************************* + struct width_spec + { + ETL_CONSTEXPR width_spec(uint_least8_t width_) + : width(width_) + { + } + + const uint_least8_t width; + }; + + //********************************* + template + struct fill_spec + { + ETL_CONSTEXPR fill_spec(TChar fill_) + : fill(fill_) + { + } + + const TChar fill; + }; + + //********************************* + struct precision_spec + { + ETL_CONSTEXPR precision_spec(uint_least8_t precision_) + : precision(precision_) + { + } + + const uint_least8_t precision; + }; + + //********************************* + struct uppercase_spec + { + ETL_CONSTEXPR uppercase_spec(bool upper_case_) + : upper_case(upper_case_) + { + } + + const bool upper_case; + }; + + //********************************* + struct boolalpha_spec + { + ETL_CONSTEXPR boolalpha_spec(bool boolalpha_) + : boolalpha(boolalpha_) + { + } + + const bool boolalpha; + }; + + //********************************* + struct showbase_spec + { + ETL_CONSTEXPR showbase_spec(bool show_base_) + : show_base(show_base_) + { + } + + const bool show_base; + }; + + //********************************* + struct left_spec + { + }; + + //********************************* + struct right_spec + { + }; + } + + //*************************************************************************** + // Stream formatting manipulators. + //*************************************************************************** + static ETL_CONSTEXPR private_basic_format_spec::base_spec setbase(uint32_t base) + { + return private_basic_format_spec::base_spec(base); + } + + //********************************* + static ETL_CONSTEXPR private_basic_format_spec::width_spec setw(uint32_t width) + { + return private_basic_format_spec::width_spec(width); + } + + //********************************* + template + static ETL_CONSTEXPR private_basic_format_spec::fill_spec setfill(TChar fill) + { + return private_basic_format_spec::fill_spec(fill); + } + + //********************************* + static ETL_CONSTEXPR private_basic_format_spec::precision_spec setprecision(uint32_t precision) + { + return private_basic_format_spec::precision_spec(precision); + } + + //********************************* + static ETL_CONSTANT private_basic_format_spec::base_spec bin = { 2U }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::base_spec oct = { 8U }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::base_spec dec = { 10U }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::base_spec hex = { 16U }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::left_spec left; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::right_spec right; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::boolalpha_spec boolalpha = { true }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::boolalpha_spec noboolalpha = { false }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::uppercase_spec uppercase = { true }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::uppercase_spec nouppercase = { false }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::showbase_spec showbase = { true }; + + //********************************* + static ETL_CONSTANT private_basic_format_spec::showbase_spec noshowbase = { false }; + + //*************************************************************************** + /// basic_format_spec + //*************************************************************************** template class basic_format_spec { @@ -46,29 +205,61 @@ namespace etl //*************************************************************************** /// Default constructor. - /// Sets:- - /// Base = 10 - /// Width = 0 - /// Upper case (for hex) = true - /// Left Justified = false //*************************************************************************** - basic_format_spec() - : base_(10) - , width_(0) - , precision_(0) - , upper_case_(true) + ETL_CONSTEXPR basic_format_spec() + : base_(10U) + , width_(0U) + , precision_(0U) + , upper_case_(false) , left_justified_(false) , boolalpha_(false) + , show_base_(false) , fill_(typename TString::value_type(' ')) { + } + //*************************************************************************** + /// Cconstructor. + //*************************************************************************** + ETL_CONSTEXPR basic_format_spec(uint_least8_t base__, + uint_least8_t width__, + uint_least8_t precision__, + bool upper_case__, + bool left_justified__, + bool boolalpha__, + bool show_base__, + typename TString::value_type fill__) + : base_(base__) + , width_(width__) + , precision_(precision__) + , upper_case_(upper_case__) + , left_justified_(left_justified__) + , boolalpha_(boolalpha__) + , show_base_(show_base__) + , fill_(fill__) + { + } + + //*************************************************************************** + /// Clears the format spec back to default. + //*************************************************************************** + ETL_CONSTEXPR14 void clear() + { + base_ = 10U; + width_ = 0U; + precision_ = 0U; + upper_case_ = false; + left_justified_ = false; + boolalpha_ = false; + show_base_ = false; + fill_ = typename TString::value_type(' '); } //*************************************************************************** /// Sets the base. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& base(const uint32_t b) + ETL_CONSTEXPR14 basic_format_spec& base(uint32_t b) { base_ = static_cast(b); return *this; @@ -78,7 +269,7 @@ namespace etl /// Sets the base to binary. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& binary() + ETL_CONSTEXPR14 basic_format_spec& binary() { base(2); return *this; @@ -88,7 +279,7 @@ namespace etl /// Sets the base to octal. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& octal() + ETL_CONSTEXPR14 basic_format_spec& octal() { base(8); return *this; @@ -98,7 +289,7 @@ namespace etl /// Sets the base to decimal. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& decimal() + ETL_CONSTEXPR14 basic_format_spec& decimal() { base(10); return *this; @@ -108,7 +299,7 @@ namespace etl /// Sets the base to hex. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& hex() + ETL_CONSTEXPR14 basic_format_spec& hex() { base(16); return *this; @@ -117,16 +308,34 @@ namespace etl //*************************************************************************** /// Gets the base. //*************************************************************************** - uint32_t get_base() const + ETL_CONSTEXPR uint32_t get_base() const { return base_; } + //*************************************************************************** + /// Sets the show base flag. + /// \return A reference to the basic_format_spec. + //*************************************************************************** + ETL_CONSTEXPR14 basic_format_spec& show_base(bool b) + { + show_base_ = b; + return *this; + } + + //*************************************************************************** + /// Gets the show base flag. + //*************************************************************************** + ETL_CONSTEXPR bool is_show_base() const + { + return show_base_; + } + //*************************************************************************** /// Sets the width. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& width(const uint32_t w) + ETL_CONSTEXPR14 basic_format_spec& width(uint32_t w) { width_ = static_cast(w); return *this; @@ -135,7 +344,7 @@ namespace etl //*************************************************************************** /// Gets the width. //*************************************************************************** - uint32_t get_width() const + ETL_CONSTEXPR uint32_t get_width() const { return width_; } @@ -144,16 +353,16 @@ namespace etl /// Sets the precision. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& precision(const uint32_t w) + ETL_CONSTEXPR14 basic_format_spec& precision(uint32_t p) { - precision_ = static_cast(w); + precision_ = static_cast(p); return *this; } //*************************************************************************** /// Gets the precision. //*************************************************************************** - uint32_t get_precision() const + ETL_CONSTEXPR uint32_t get_precision() const { return precision_; } @@ -162,7 +371,7 @@ namespace etl /// Sets the upper case flag. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& upper_case(const bool u) + ETL_CONSTEXPR14 basic_format_spec& upper_case(bool u) { upper_case_ = u; return *this; @@ -171,7 +380,7 @@ namespace etl //*************************************************************************** /// Gets the upper case flag. //*************************************************************************** - bool is_upper_case() const + ETL_CONSTEXPR bool is_upper_case() const { return upper_case_; } @@ -180,7 +389,7 @@ namespace etl /// Sets the fill character. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& fill(const typename TString::value_type c) + ETL_CONSTEXPR14 basic_format_spec& fill(typename TString::value_type c) { fill_ = c; return *this; @@ -189,7 +398,7 @@ namespace etl //*************************************************************************** /// Gets the fill character. //*************************************************************************** - typename TString::value_type get_fill() const + ETL_CONSTEXPR typename TString::value_type get_fill() const { return fill_; } @@ -198,7 +407,7 @@ namespace etl /// Sets the left justify flag. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& left() + ETL_CONSTEXPR14 basic_format_spec& left() { left_justified_ = true; return *this; @@ -207,7 +416,7 @@ namespace etl //*************************************************************************** /// Gets the left justify flag. //*************************************************************************** - bool is_left() const + ETL_CONSTEXPR bool is_left() const { return left_justified_; } @@ -216,7 +425,7 @@ namespace etl /// Sets the right justify flag. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& right() + ETL_CONSTEXPR14 basic_format_spec& right() { left_justified_ = false; return *this; @@ -225,7 +434,7 @@ namespace etl //*************************************************************************** /// Gets the right justify flag. //*************************************************************************** - bool is_right() const + ETL_CONSTEXPR bool is_right() const { return !left_justified_; } @@ -234,7 +443,7 @@ namespace etl /// Sets the bool alpha flag. /// \return A reference to the basic_format_spec. //*************************************************************************** - basic_format_spec& boolalpha(bool b) + ETL_CONSTEXPR14 basic_format_spec& boolalpha(bool b) { boolalpha_ = b; return *this; @@ -243,11 +452,34 @@ namespace etl //*************************************************************************** /// Gets the boolalpha flag. //*************************************************************************** - bool is_boolalpha() const + ETL_CONSTEXPR bool is_boolalpha() const { return boolalpha_; } + //*************************************************************************** + /// Equality operator. + //*************************************************************************** + ETL_CONSTEXPR friend bool operator ==(const basic_format_spec& lhs, const basic_format_spec& rhs) + { + return (lhs.base_ == rhs.base_) && + (lhs.width_ == rhs.width_) && + (lhs.precision_ == rhs.precision_) && + (lhs.upper_case_ == rhs.upper_case_) && + (lhs.left_justified_ == rhs.left_justified_) && + (lhs.boolalpha_ == rhs.boolalpha_) && + (lhs.show_base_ == rhs.show_base_) && + (lhs.fill_ == rhs.fill_); + } + + //*************************************************************************** + /// Inequality operator. + //*************************************************************************** + ETL_CONSTEXPR friend bool operator !=(const basic_format_spec& lhs, const basic_format_spec& rhs) + { + return !(lhs == rhs); + } + private: uint_least8_t base_; @@ -256,6 +488,7 @@ namespace etl bool upper_case_; bool left_justified_; bool boolalpha_; + bool show_base_; typename TString::value_type fill_; }; } diff --git a/include/etl/basic_string.h b/include/etl/basic_string.h index 9a3b2852..011d9f5c 100644 --- a/include/etl/basic_string.h +++ b/include/etl/basic_string.h @@ -50,9 +50,9 @@ SOFTWARE. #include "integral_limits.h" #include "exception.h" #include "memory.h" - -#undef ETL_FILE -#define ETL_FILE "27" +#include "exception.h" +#include "binary.h" +#include "flags.h" #ifdef ETL_COMPILER_GCC #pragma GCC diagnostic push @@ -92,7 +92,7 @@ namespace etl public: string_empty(string_type file_name_, numeric_type line_number_) - : string_exception(ETL_ERROR_TEXT("string:empty", ETL_FILE"A"), file_name_, line_number_) + : string_exception(ETL_ERROR_TEXT("string:empty", ETL_STRING_FILE_ID"A"), file_name_, line_number_) { } }; @@ -106,7 +106,7 @@ namespace etl public: string_out_of_bounds(string_type file_name_, numeric_type line_number_) - : string_exception(ETL_ERROR_TEXT("string:bounds", ETL_FILE"B"), file_name_, line_number_) + : string_exception(ETL_ERROR_TEXT("string:bounds", ETL_STRING_FILE_ID"B"), file_name_, line_number_) { } }; @@ -120,7 +120,7 @@ namespace etl public: string_iterator(string_type file_name_, numeric_type line_number_) - : string_exception(ETL_ERROR_TEXT("string:iterator", ETL_FILE"C"), file_name_, line_number_) + : string_exception(ETL_ERROR_TEXT("string:iterator", ETL_STRING_FILE_ID"C"), file_name_, line_number_) { } }; @@ -134,7 +134,7 @@ namespace etl public: string_truncation(string_type file_name_, numeric_type line_number_) - : string_exception(ETL_ERROR_TEXT("string:iterator", ETL_FILE"D"), file_name_, line_number_) + : string_exception(ETL_ERROR_TEXT("string:iterator", ETL_STRING_FILE_ID"D"), file_name_, line_number_) { } }; @@ -149,10 +149,14 @@ namespace etl typedef size_t size_type; +#if ETL_CPP11_SUPPORTED + static constexpr size_type npos = etl::integral_limits::max; +#else enum { - npos = etl::integral_limits::max + npos = etl::integral_limits::max }; +#endif //************************************************************************* /// Gets the current size of the string. @@ -212,18 +216,30 @@ namespace etl /// Returns the remaining capacity. ///\return The remaining capacity. //************************************************************************* - size_t available() const + size_type available() const { return max_size() - size(); } +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + //************************************************************************* + /// Returns whether the string was truncated by the last operation. + /// Deprecated. Use is_truncated() + ///\return Whether the string was truncated by the last operation. + //************************************************************************* + ETL_DEPRECATED + bool truncated() const + { + return flags.test(); + } + //************************************************************************* /// Returns whether the string was truncated by the last operation. ///\return Whether the string was truncated by the last operation. //************************************************************************* - size_t truncated() const + bool is_truncated() const { - return is_truncated; + return flags.test(); } //************************************************************************* @@ -231,15 +247,17 @@ namespace etl //************************************************************************* void clear_truncated() { - is_truncated = false; + flags.set(); } +#endif +#if ETL_STRING_CLEAR_AFTER_USE_ENABLED //************************************************************************* /// Sets the 'secure' flag to the requested state. //************************************************************************* void set_secure() { - clear_afer_use = true; + flags.set(); } //************************************************************************* @@ -247,22 +265,31 @@ namespace etl //************************************************************************* bool is_secure() const { - return clear_afer_use; + return flags.test(); } +#endif protected: //************************************************************************* /// Constructor. //************************************************************************* - string_base(size_t max_size_) - : is_truncated(false) - , clear_afer_use(false) - , current_size(0) + string_base(size_type max_size_) + : current_size(0) , CAPACITY(max_size_) { } +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + //************************************************************************* + /// Sets the 'truncated' flag. + //************************************************************************* + void set_truncated(bool status) + { + flags.set(status); + } +#endif + //************************************************************************* /// Destructor. //************************************************************************* @@ -270,10 +297,15 @@ namespace etl { } - bool is_truncated; ///< Set to true if the operation truncated the string. - bool clear_afer_use; ///< Set to true if the string must be cleared after use. + static const uint_least8_t IS_TRUNCATED = etl::bit<0>::value; + static const uint_least8_t CLEAR_AFTER_USE = etl::bit<1>::value; + size_type current_size; ///< The current number of elements in the string. const size_type CAPACITY; ///< The maximum number of elements in the string. + +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED || ETL_STRING_CLEAR_AFTER_USE_ENABLED + etl::flags flags; +#endif }; //*************************************************************************** @@ -297,7 +329,6 @@ namespace etl typedef const T* const_iterator; typedef ETL_OR_STD::reverse_iterator reverse_iterator; typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; - typedef size_t size_type; typedef typename etl::iterator_traits::difference_type difference_type; @@ -414,7 +445,7 @@ namespace etl /// If asserts or exceptions are enabled and the new size is larger than the ///\param new_size The new size. //********************************************************************* - void resize(size_t new_size) + void resize(size_type new_size) { resize(new_size, 0); } @@ -424,14 +455,16 @@ namespace etl ///\param new_size The new size. ///\param value The value to fill new elements with. Default = default constructed value. //********************************************************************* - void resize(size_t new_size, T value) + void resize(size_type new_size, T value) { if (new_size > CAPACITY) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } @@ -448,12 +481,25 @@ namespace etl cleanup(); } + //********************************************************************* + /// Resizes the string, but doesn't initialise the free space + /// except for a terminator null. + ///\param new_size The new size. + //********************************************************************* + void uninitialized_resize(size_type new_size) + { + new_size = etl::min(new_size, CAPACITY); + + current_size = new_size; + p_buffer[new_size] = 0; + } + //********************************************************************* /// Returns a reference to the value at index 'i' ///\param i The index. ///\return A reference to the value at index 'i' //********************************************************************* - reference operator [](size_t i) + reference operator [](size_type i) { return p_buffer[i]; } @@ -463,7 +509,7 @@ namespace etl ///\param i The index. ///\return A const reference to the value at index 'i' //********************************************************************* - const_reference operator [](size_t i) const + const_reference operator [](size_type i) const { return p_buffer[i]; } @@ -474,7 +520,7 @@ namespace etl ///\param i The index. ///\return A reference to the value at index 'i' //********************************************************************* - reference at(size_t i) + reference at(size_type i) { ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds)); return p_buffer[i]; @@ -486,7 +532,7 @@ namespace etl ///\param i The index. ///\return A const reference to the value at index 'i' //********************************************************************* - const_reference at(size_t i) const + const_reference at(size_type i) const { ETL_ASSERT(i < size(), ETL_ERROR(string_out_of_bounds)); return p_buffer[i]; @@ -546,6 +592,24 @@ namespace etl return p_buffer; } + //********************************************************************* + /// Returns a pointer to the beginning of the string data. + ///\return A pointer to the beginning of the string data. + //********************************************************************* + pointer data_end() + { + return p_buffer + current_size; + } + + //********************************************************************* + /// Returns a const pointer to the beginning of the string data. + ///\return A const pointer to the beginning of the string data. + //********************************************************************* + const_pointer data_end() const + { + return p_buffer + current_size; + } + //********************************************************************* /// Assigns values to the string. /// Truncates if the string does not have enough free space. @@ -555,14 +619,23 @@ namespace etl { assign(other.begin(), other.end()); - if (other.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (other.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif + +#if ETL_STRING_CLEAR_AFTER_USE_ENABLED + if (other.is_secure()) + { + set_secure(); + } +#endif cleanup(); } @@ -574,7 +647,7 @@ namespace etl ///\param subposition The position to start from. ///\param sublength The length to copy. //********************************************************************* - void assign(const etl::ibasic_string& other, size_t subposition, size_t sublength) + void assign(const etl::ibasic_string& other, size_type subposition, size_type sublength) { if (sublength == npos) { @@ -584,6 +657,24 @@ namespace etl ETL_ASSERT(subposition <= other.size(), ETL_ERROR(string_out_of_bounds)); assign(other.begin() + subposition, sublength); + +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (other.is_truncated()) + { + this->set_truncated(true); + +#if defined(ETL_STRING_TRUNCATION_IS_ERROR) + ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif + } +#endif + +#if ETL_STRING_CLEAR_AFTER_USE_ENABLED + if (other.is_secure()) + { + set_secure(); + } +#endif } //********************************************************************* @@ -600,10 +691,12 @@ namespace etl p_buffer[current_size++] = *other++; } - is_truncated = (*other != 0); +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(*other != 0); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) - ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation)) + ETL_ASSERT(flags.test() == false, ETL_ERROR(string_truncation)) +#endif #endif p_buffer[current_size] = 0; @@ -615,14 +708,16 @@ namespace etl ///\param other The other string. ///\param length The length to copy. //********************************************************************* - void assign(const_pointer other, size_t length_) + void assign(const_pointer other, size_type length_) { initialise(); - is_truncated = (length_ > CAPACITY); +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(length_ > CAPACITY); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) - ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation)) + ETL_ASSERT(flags.test() == false, ETL_ERROR(string_truncation)) +#endif #endif length_ = etl::min(length_, CAPACITY); @@ -657,10 +752,12 @@ namespace etl p_buffer[current_size] = 0; - is_truncated = (first != last); +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(first != last); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) - ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation)) + ETL_ASSERT(flags.test() == false, ETL_ERROR(string_truncation)) +#endif #endif } @@ -670,14 +767,16 @@ namespace etl ///\param n The number of elements to add. ///\param value The value to insert for each element. //********************************************************************* - void assign(size_t n, T value) + void assign(size_type n, T value) { initialise(); - is_truncated = (n > CAPACITY); +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(n > CAPACITY); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) - ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation)) + ETL_ASSERT(flags.test() == false, ETL_ERROR(string_truncation)) +#endif #endif n = etl::min(n, CAPACITY); @@ -709,10 +808,12 @@ namespace etl } else { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } } @@ -737,14 +838,16 @@ namespace etl { insert(end(), str.begin(), str.end()); - if (str.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (str.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif return *this; } @@ -755,7 +858,7 @@ namespace etl ///\param subposition The position in str. ///\param sublength The number of characters. //********************************************************************* - ibasic_string& append(const ibasic_string& str, size_t subposition, size_t sublength = npos) + ibasic_string& append(const ibasic_string& str, size_type subposition, size_type sublength = npos) { ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds)); @@ -779,7 +882,7 @@ namespace etl ///\param str The string to append. ///\param n The number of characters. //********************************************************************* - ibasic_string& append(const T* str, size_t n) + ibasic_string& append(const T* str, size_type n) { insert(size(), str, n); return *this; @@ -790,7 +893,7 @@ namespace etl ///\param n The number of characters. ///\param c The character. //********************************************************************* - ibasic_string& append(size_t n, T c) + ibasic_string& append(size_type n, T c) { insert(size(), n, c); return *this; @@ -845,10 +948,12 @@ namespace etl *insert_position = value; } - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } @@ -863,7 +968,7 @@ namespace etl ///\param n The number of elements to add. ///\param value The value to insert. //********************************************************************* - void insert(const_iterator position, size_t n, T value) + void insert(const_iterator position, size_type n, T value) { if (n == 0) { @@ -872,15 +977,17 @@ namespace etl // Quick hack, as iterators are pointers. iterator insert_position = const_cast(position); - const size_t start = etl::distance(cbegin(), position); + const size_type start = etl::distance(cbegin(), position); // No effect. if (start >= CAPACITY) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif return; } @@ -890,10 +997,12 @@ namespace etl { if ((current_size + n) > CAPACITY) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } @@ -903,20 +1012,23 @@ namespace etl else { // Lets do some shifting. - const size_t shift_amount = n; - const size_t to_position = start + shift_amount; - const size_t remaining_characters = current_size - start; - const size_t max_shift_characters = CAPACITY - start - shift_amount; - const size_t characters_to_shift = etl::min(max_shift_characters, remaining_characters); + const size_type shift_amount = n; + const size_type to_position = start + shift_amount; + const size_type remaining_characters = current_size - start; + const size_type max_shift_characters = CAPACITY - start - shift_amount; + const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters); // Will the string truncate? if ((start + shift_amount + remaining_characters) > CAPACITY) { current_size = CAPACITY; - is_truncated = true; + +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } else @@ -946,16 +1058,18 @@ namespace etl return; } - const size_t start = etl::distance(begin(), position); - const size_t n = etl::distance(first, last); + const size_type start = etl::distance(begin(), position); + const size_type n = etl::distance(first, last); // No effect. if (start >= CAPACITY) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif return; } @@ -965,10 +1079,12 @@ namespace etl { if (((current_size + n) > CAPACITY)) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } @@ -982,20 +1098,23 @@ namespace etl else { // Lets do some shifting. - const size_t shift_amount = n; - const size_t to_position = start + shift_amount; - const size_t remaining_characters = current_size - start; - const size_t max_shift_characters = CAPACITY - start - shift_amount; - const size_t characters_to_shift = etl::min(max_shift_characters, remaining_characters); + const size_type shift_amount = n; + const size_type to_position = start + shift_amount; + const size_type remaining_characters = current_size - start; + const size_type max_shift_characters = CAPACITY - start - shift_amount; + const size_type characters_to_shift = etl::min(max_shift_characters, remaining_characters); // Will the string truncate? if ((start + shift_amount + remaining_characters) > CAPACITY) { current_size = CAPACITY; - is_truncated = true; + +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } else @@ -1019,20 +1138,22 @@ namespace etl ///\param position The position to insert before. ///\param str The string to insert. //********************************************************************* - etl::ibasic_string& insert(size_t position, const etl::ibasic_string& str) + etl::ibasic_string& insert(size_type position, const etl::ibasic_string& str) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); insert(begin() + position, str.cbegin(), str.cend()); - if (str.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (str.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif return *this; } @@ -1044,7 +1165,7 @@ namespace etl ///\param subposition The subposition to start from. ///\param sublength The number of characters to insert. //********************************************************************* - etl::ibasic_string& insert(size_t position, const etl::ibasic_string& str, size_t subposition, size_t sublength) + etl::ibasic_string& insert(size_type position, const etl::ibasic_string& str, size_type subposition, size_type sublength) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds)); @@ -1056,14 +1177,16 @@ namespace etl insert(begin() + position, str.cbegin() + subposition, str.cbegin() + subposition + sublength); - if (str.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (str.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif return *this; } @@ -1073,7 +1196,7 @@ namespace etl ///\param position The position to insert before. ///\param s The string to insert. //********************************************************************* - etl::ibasic_string& insert(size_t position, const_pointer s) + etl::ibasic_string& insert(size_type position, const_pointer s) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1087,7 +1210,7 @@ namespace etl ///\param s The string to insert. ///\param n The number of characters to insert. //********************************************************************* - etl::ibasic_string& insert(size_t position, const_pointer s, size_t n) + etl::ibasic_string& insert(size_type position, const_pointer s, size_type n) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1101,7 +1224,7 @@ namespace etl ///\param n The number of characters to insert. ///\param c The character to insert. //********************************************************************* - etl::ibasic_string& insert(size_t position, size_t n, value_type c) + etl::ibasic_string& insert(size_type position, size_type n, value_type c) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1115,7 +1238,7 @@ namespace etl ///\param length Number of characters. ///\return A refernce to this string. //********************************************************************* - etl::ibasic_string& erase(size_t position, size_t length_ = npos) + etl::ibasic_string& erase(size_type position, size_type length_ = npos) { // Limit the length. length_ = etl::min(length_, size() - position); @@ -1148,8 +1271,13 @@ namespace etl //********************************************************************* iterator erase(iterator first, iterator last) { + if (first == last) + { + return first; + } + etl::copy(last, end(), first); - size_t n_delete = etl::distance(first, last); + size_type n_delete = etl::distance(first, last); current_size -= n_delete; p_buffer[current_size] = 0; @@ -1172,20 +1300,22 @@ namespace etl ///\param len The number of characters to copy. ///\param pos The position to start copying from. //********************************************************************* - size_t copy(pointer s, size_t len, size_t pos = 0) + size_type copy(pointer s, size_type len, size_type pos = 0) { if ((pos + len > size())) { - is_truncated = true; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); +#endif #endif } - size_t endpos = etl::min(pos + len, size()); + size_type endpos = etl::min(pos + len, size()); - for (size_t i = pos; i < endpos; ++i) + for (size_type i = pos; i < endpos; ++i) { *s++ = p_buffer[i]; } @@ -1198,7 +1328,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find(const ibasic_string& str, size_t pos = 0) const + size_type find(const ibasic_string& str, size_type pos = 0) const { if ((pos + str.size()) > size()) { @@ -1222,7 +1352,7 @@ namespace etl ///\param s Pointer to the content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find(const_pointer s, size_t pos = 0) const + size_type find(const_pointer s, size_type pos = 0) const { #if defined(ETL_DEBUG) if ((pos + etl::strlen(s)) > size()) @@ -1249,7 +1379,7 @@ namespace etl ///\param pos The position to start searching from. ///\param n The number of characters to search for. //********************************************************************* - size_t find(const_pointer s, size_t pos, size_t n) const + size_type find(const_pointer s, size_type pos, size_type n) const { #if defined(ETL_DEBUG) if ((pos + etl::strlen(s) - n) > size()) @@ -1275,7 +1405,7 @@ namespace etl ///\param c The character to find. ///\param position The position to start searching from. //********************************************************************* - size_t find(T c, size_t position = 0) const + size_type find(T c, size_type position = 0) const { const_iterator i = etl::find(begin() + position, end(), c); @@ -1294,7 +1424,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t rfind(const ibasic_string& str, size_t position = npos) const + size_type rfind(const ibasic_string& str, size_type position = npos) const { if ((str.size()) > size()) { @@ -1325,9 +1455,9 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t rfind(const_pointer s, size_t position = npos) const + size_type rfind(const_pointer s, size_type position = npos) const { - size_t len = etl::strlen(s); + size_type len = etl::strlen(s); if (len > size()) { @@ -1361,7 +1491,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t rfind(const_pointer s, size_t position, size_t length_) const + size_type rfind(const_pointer s, size_type position, size_type length_) const { if (length_ > size()) { @@ -1395,7 +1525,7 @@ namespace etl ///\param c The character to find ///\param pos The position to start searching from. //********************************************************************* - size_t rfind(T c, size_t position = npos) const + size_type rfind(T c, size_type position = npos) const { if (position >= size()) { @@ -1422,7 +1552,7 @@ namespace etl ///\param length The number of characters to replace. ///\param str The string to replace it with. //********************************************************************* - ibasic_string& replace(size_t position, size_t length_, const ibasic_string& str) + ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1456,14 +1586,16 @@ namespace etl // Insert the new stuff. insert(first_, str.begin(), str.end()); - if (str.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (str.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif return *this; } @@ -1471,7 +1603,7 @@ namespace etl //********************************************************************* /// Replace characters from 'position' of 'length' with 'str' from 'subpsotion' of 'sublength'. //********************************************************************* - ibasic_string& replace(size_t position, size_t length_, const ibasic_string& str, size_t subposition, size_t sublength) + ibasic_string& replace(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds)); @@ -1486,14 +1618,16 @@ namespace etl // Insert the new stuff. insert(position, str, subposition, sublength); - if (str.truncated()) +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + if (str.is_truncated()) { - is_truncated = true; + set_truncated(true); #if defined(ETL_STRING_TRUNCATION_IS_ERROR) ETL_ALWAYS_ASSERT(ETL_ERROR(string_truncation)); #endif } +#endif return *this; } @@ -1501,7 +1635,7 @@ namespace etl //********************************************************************* /// Replace characters from 'position' of 'length' with pointed to string. //********************************************************************* - ibasic_string& replace(size_t position, size_t length_, const_pointer s) + ibasic_string& replace(size_type position, size_type length_, const_pointer s) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1538,7 +1672,7 @@ namespace etl //********************************************************************* /// Replace characters from 'position' of 'length' with 'n' characters from pointed to string. //********************************************************************* - ibasic_string& replace(size_t position, size_t length_, const_pointer s, size_t n) + ibasic_string& replace(size_type position, size_type length_, const_pointer s, size_type n) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1557,7 +1691,7 @@ namespace etl //********************************************************************* /// Replace characters from 'first' to 'last' with 'n' characters from pointed to string. //********************************************************************* - ibasic_string& replace(const_iterator first, const_iterator last, const_pointer s, size_t n) + ibasic_string& replace(const_iterator first, const_iterator last, const_pointer s, size_type n) { // Quick hack, as iterators are pointers. iterator first_ = const_cast(first); @@ -1575,7 +1709,7 @@ namespace etl //********************************************************************* /// Replace characters from 'position' of 'length' with 'n' copies of 'c'. //********************************************************************* - ibasic_string& replace(size_t position, size_t length_, size_t n, value_type c) + ibasic_string& replace(size_type position, size_type length_, size_type n, value_type c) { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1594,7 +1728,7 @@ namespace etl //********************************************************************* /// Replace characters from 'first' of 'last' with 'n' copies of 'c'. //********************************************************************* - ibasic_string& replace(const_iterator first, const_iterator last, size_t n, value_type c) + ibasic_string& replace(const_iterator first, const_iterator last, size_type n, value_type c) { // Quick hack, as iterators are pointers. iterator first_ = const_cast(first); @@ -1642,7 +1776,7 @@ namespace etl //************************************************************************* /// Compare position / length with string. //************************************************************************* - int compare(size_t position, size_t length_, const ibasic_string& str) const + int compare(size_type position, size_type length_, const ibasic_string& str) const { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); @@ -1658,7 +1792,7 @@ namespace etl //************************************************************************* /// Compare position / length with string / subposition / sublength. //************************************************************************* - int compare(size_t position, size_t length_, const ibasic_string& str, size_t subposition, size_t sublength) const + int compare(size_type position, size_type length_, const ibasic_string& str, size_type subposition, size_type sublength) const { ETL_ASSERT(position <= size(), ETL_ERROR(string_out_of_bounds)); ETL_ASSERT(subposition <= str.size(), ETL_ERROR(string_out_of_bounds)); @@ -1687,7 +1821,7 @@ namespace etl //************************************************************************* /// Compare position / length with C string. //************************************************************************* - int compare(size_t position, size_t length_, const_pointer s) const + int compare(size_type position, size_type length_, const_pointer s) const { return compare(p_buffer + position, p_buffer + position + length_, @@ -1698,7 +1832,7 @@ namespace etl //************************************************************************* /// Compare position / length with C string / n. //************************************************************************* - int compare(size_t position, size_t length_, const_pointer s, size_t n) const + int compare(size_type position, size_type length_, const_pointer s, size_type n) const { return compare(p_buffer + position, p_buffer + position + length_, @@ -1711,7 +1845,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_of(const ibasic_string& str, size_t position = 0) const + size_type find_first_of(const ibasic_string& str, size_type position = 0) const { return find_first_of(str.c_str(), position, str.size()); } @@ -1721,7 +1855,7 @@ namespace etl ///\param s Pointer to the content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_of(const_pointer s, size_t position = 0) const + size_type find_first_of(const_pointer s, size_type position = 0) const { return find_first_of(s, position, etl::strlen(s)); } @@ -1732,13 +1866,13 @@ namespace etl ///\param pos The position to start searching from. ///\param n The number of characters to search for. //********************************************************************* - size_t find_first_of(const_pointer s, size_t position, size_t n) const + size_type find_first_of(const_pointer s, size_type position, size_type n) const { if (position < size()) { - for (size_t i = position; i < size(); ++i) + for (size_type i = position; i < size(); ++i) { - for (size_t j = 0; j < n; ++j) + for (size_type j = 0; j < n; ++j) { if (p_buffer[i] == s[j]) { @@ -1756,11 +1890,11 @@ namespace etl ///\param c The character to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_of(value_type c, size_t position = 0) const + size_type find_first_of(value_type c, size_type position = 0) const { if (position < size()) { - for (size_t i = position; i < size(); ++i) + for (size_type i = position; i < size(); ++i) { if (p_buffer[i] == c) { @@ -1777,7 +1911,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_last_of(const ibasic_string& str, size_t position = npos) const + size_type find_last_of(const ibasic_string& str, size_type position = npos) const { return find_last_of(str.c_str(), position, str.size()); } @@ -1787,7 +1921,7 @@ namespace etl ///\param s Pointer to the content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_last_of(const_pointer s, size_t position = npos) const + size_type find_last_of(const_pointer s, size_type position = npos) const { return find_last_of(s, position, etl::strlen(s)); } @@ -1798,7 +1932,7 @@ namespace etl ///\param pos The position to start searching from. ///\param n The number of characters to search for. //********************************************************************* - size_t find_last_of(const_pointer s, size_t position, size_t n) const + size_type find_last_of(const_pointer s, size_type position, size_type n) const { if (empty()) { @@ -1811,7 +1945,7 @@ namespace etl while (it != rend()) { - for (size_t j = 0; j < n; ++j) + for (size_type j = 0; j < n; ++j) { if (p_buffer[position] == s[j]) { @@ -1831,7 +1965,7 @@ namespace etl ///\param c The character to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_last_of(value_type c, size_t position = npos) const + size_type find_last_of(value_type c, size_type position = npos) const { if (empty()) { @@ -1861,7 +1995,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_not_of(const ibasic_string& str, size_t position = 0) const + size_type find_first_not_of(const ibasic_string& str, size_type position = 0) const { return find_first_not_of(str.c_str(), position, str.size()); } @@ -1871,7 +2005,7 @@ namespace etl ///\param s Pointer to the content to not find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_not_of(const_pointer s, size_t position = 0) const + size_type find_first_not_of(const_pointer s, size_type position = 0) const { return find_first_not_of(s, position, etl::strlen(s)); } @@ -1882,15 +2016,15 @@ namespace etl ///\param pos The position to start searching from. ///\param n The number of characters to search for. //********************************************************************* - size_t find_first_not_of(const_pointer s, size_t position, size_t n) const + size_type find_first_not_of(const_pointer s, size_type position, size_type n) const { if (position < size()) { - for (size_t i = position; i < size(); ++i) + for (size_type i = position; i < size(); ++i) { bool found = false; - for (size_t j = 0; j < n; ++j) + for (size_type j = 0; j < n; ++j) { if (p_buffer[i] == s[j]) { @@ -1913,11 +2047,11 @@ namespace etl ///\param c The character to not find ///\param pos The position to start searching from. //********************************************************************* - size_t find_first_not_of(value_type c, size_t position = 0) const + size_type find_first_not_of(value_type c, size_type position = 0) const { if (position < size()) { - for (size_t i = position; i < size(); ++i) + for (size_type i = position; i < size(); ++i) { if (p_buffer[i] != c) { @@ -1934,7 +2068,7 @@ namespace etl ///\param str The content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_last_not_of(const ibasic_string& str, size_t position = npos) const + size_type find_last_not_of(const ibasic_string& str, size_type position = npos) const { return find_last_not_of(str.c_str(), position, str.size()); } @@ -1944,7 +2078,7 @@ namespace etl ///\param s The pointer to the content to find ///\param pos The position to start searching from. //********************************************************************* - size_t find_last_not_of(const_pointer s, size_t position = npos) const + size_type find_last_not_of(const_pointer s, size_type position = npos) const { return find_last_not_of(s, position, etl::strlen(s)); } @@ -1955,7 +2089,7 @@ namespace etl ///\param pos The position to start searching from. ///\param n The number of characters to use. //********************************************************************* - size_t find_last_not_of(const_pointer s, size_t position, size_t n) const + size_type find_last_not_of(const_pointer s, size_type position, size_type n) const { if (empty()) { @@ -1970,7 +2104,7 @@ namespace etl { bool found = false; - for (size_t j = 0; j < n; ++j) + for (size_type j = 0; j < n; ++j) { if (p_buffer[position] == s[j]) { @@ -1993,7 +2127,7 @@ namespace etl //********************************************************************* // //********************************************************************* - size_t find_last_not_of(value_type c, size_t position = npos) const + size_type find_last_not_of(value_type c, size_type position = npos) const { if (empty()) { @@ -2066,7 +2200,7 @@ namespace etl //************************************************************************* ibasic_string& operator += (T rhs) { - append(size_t(1), rhs); + append(size_type(1), rhs); return *this; } @@ -2078,12 +2212,38 @@ namespace etl virtual void repair() = 0; #endif + //********************************************************************* + /// Clears the free space to string terminator value. + //********************************************************************* + void initialize_free_space() + { +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(false); +#endif + etl::fill(&p_buffer[current_size], &p_buffer[CAPACITY + 1U], T(0)); + } + + //********************************************************************* + /// Trim the size to the distance to the first null terminator. + /// If the last buffer position has a non-null value then the truncated + /// flag will be set. + //********************************************************************* + void trim_to_terminator() + { +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(p_buffer[CAPACITY] != T(0)); +#endif + + p_buffer[CAPACITY] = T(0); // Ensure a terminating null. + current_size = etl::strlen(p_buffer); + } + protected: //********************************************************************* /// Constructor. //********************************************************************* - ibasic_string(T* p_buffer_, size_t MAX_SIZE_) + ibasic_string(T* p_buffer_, size_type MAX_SIZE_) : string_base(MAX_SIZE_), p_buffer(p_buffer_) { @@ -2094,10 +2254,12 @@ namespace etl //********************************************************************* void initialise() { - current_size = 0; + current_size = 0U; cleanup(); p_buffer[0] = 0; - is_truncated = false; +#if ETL_STRING_TRUNCATION_CHECKS_ENABLED + set_truncated(false); +#endif } //************************************************************************* @@ -2155,10 +2317,12 @@ namespace etl //************************************************************************* void cleanup() { +#if ETL_STRING_CLEAR_AFTER_USE_ENABLED if (is_secure()) { etl::memory_clear_range(&p_buffer[current_size], &p_buffer[CAPACITY]); } +#endif } //************************************************************************* @@ -2182,10 +2346,12 @@ namespace etl #endif ~ibasic_string() { +#if ETL_STRING_CLEAR_AFTER_USE_ENABLED if (is_secure()) { initialise(); } +#endif } }; @@ -2434,6 +2600,4 @@ namespace etl #pragma GCC diagnostic pop #endif -#undef ETL_FILE - #endif diff --git a/include/etl/basic_string_stream.h b/include/etl/basic_string_stream.h new file mode 100644 index 00000000..511913e0 --- /dev/null +++ b/include/etl/basic_string_stream.h @@ -0,0 +1,269 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2020 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_BASIC_STRING_STREAM_INCLUDED +#define ETL_BASIC_STRING_STREAM_INCLUDED + +///\ingroup string + +#include "platform.h" + +namespace etl +{ + template + class basic_string_stream + { + public: + + typedef TFormat format_spec_type; + typedef TIString istring_type; + typedef typename TIString::value_type value_type; + typedef typename TIString::const_pointer const_pointer; + + //************************************************************************* + /// Construct from text. + //************************************************************************* + explicit basic_string_stream(TIString& text_) + : text(text_) + { + } + + //************************************************************************* + /// Construct from text and format spec. + //************************************************************************* + basic_string_stream(TIString& text_, const TFormat& spec_) + : text(text_) + , spec(spec_) + { + } + + //************************************************************************* + /// Set the format spec. + //************************************************************************* + void set_format(const TFormat& spec_) + { + spec = spec_; + } + + //************************************************************************* + /// Get a const reference to the format spec. + //************************************************************************* + const TFormat& get_format() const + { + return spec; + } + + //************************************************************************* + /// Get a reference to the current string. + //************************************************************************* + TIString& str() + { + return text; + } + + //************************************************************************* + /// Get a const reference to the current string. + //************************************************************************* + const TIString& str() const + { + return text; + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const value_type* p) + { + text.assign(p); + } + + //************************************************************************* + /// Resets the stream to the supplied string. + //************************************************************************* + void str(const TIString& is) + { + text.assign(is); + } + + //************************************************************************* + /// Stream operators. + //************************************************************************* + + //********************************* + /// TFormat + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, const TFormat& spec) + { + ss.spec = spec; + return ss; + } + + //********************************* + /// etl::base_spec from etl::setbase, etl::bin, etl::oct, etl::dec & etl::hex stream manipulators + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::base_spec spec) + { + ss.spec.base(spec.base); + return ss; + } + + //********************************* + /// etl::width_spec from etl::setw stream manipulator + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::width_spec spec) + { + ss.spec.width(spec.width); + return ss; + } + + //********************************* + /// etl::fill_spec from etl::setfill stream manipulator + //********************************* + template + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::fill_spec spec) + { + ss.spec.fill(spec.fill); + return ss; + } + + //********************************* + /// etl::precision_spec from etl::setprecision stream manipulator + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::precision_spec spec) + { + ss.spec.precision(spec.precision); + return ss; + } + + //********************************* + /// etl::boolalpha_spec from etl::boolalpha & etl::noboolalpha stream manipulators + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::boolalpha_spec spec) + { + ss.spec.boolalpha(spec.boolalpha); + return ss; + } + + //********************************* + /// etl::uppercase_spec from etl::uppercase & etl::nouppercase stream manipulators + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::uppercase_spec spec) + { + ss.spec.upper_case(spec.upper_case); + return ss; + } + + //********************************* + /// etl::showbase_spec from etl::showbase & etl::noshowbase stream manipulators + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::showbase_spec spec) + { + ss.spec.show_base(spec.show_base); + return ss; + } + + //********************************* + /// etl::left_spec from etl::left stream manipulator + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::left_spec spec) + { + ss.spec.left(); + return ss; + } + + //********************************* + /// etl::right_spec from etl::left stream manipulator + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::right_spec spec) + { + ss.spec.right(); + return ss; + } + + //********************************* + /// From a string view + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, TStringView view) + { + etl::to_string(view, ss.text, ss.spec, true); + return ss; + } + + //********************************* + /// From a const pointer to a string + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, const_pointer p) + { + TStringView view(p); + ss << view; + return ss; + } + + //********************************* + /// From a string interface + //********************************* + friend basic_string_stream& operator <<(basic_string_stream& ss, const TIString& text) + { + etl::to_string(text, ss.text, ss.spec, true); + return ss; + } + + //********************************* + /// From a string + //********************************* + template