Merge branch 'development' into hotfix/#649-intrusive_list-array-bounds-test-failure

# Conflicts:
#	include/etl/intrusive_forward_list.h
#	include/etl/intrusive_list.h
#	include/etl/optional.h
#	test/test_optional.cpp
#	test/vs2019/etl.vcxproj.filters
This commit is contained in:
John Wellbelove 2023-02-28 19:31:33 +00:00
commit 7bfa2d9429
80 changed files with 3658 additions and 479 deletions

View File

@ -6,12 +6,12 @@ on:
branches: [ master ]
jobs:
build-clang-9-linux-stl:
name: Clang-9 Linux - STL
build-clang-linux-stl:
name: Clang Linux - STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2
@ -19,9 +19,9 @@ jobs:
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9"
export CC=clang-9
export CXX=clang++-9
sudo apt-get install -y "clang" "lldb" "lld" "clang-format"
export CC=clang
export CXX=clang++
export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0
git fetch --tags
cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./
@ -31,12 +31,12 @@ jobs:
- name: Run tests
run: ./test/etl_tests
build-clang-9-linux-no-stl:
name: Clang-9 Linux - No STL
build-clang-linux-no-stl:
name: Clang Linux - No STL
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2
@ -44,26 +44,24 @@ jobs:
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9"
export CC=clang-9
export CXX=clang++-9
sudo apt-get install -y "clang" "lldb" "lld" "clang-format"
export CC=clang
export CXX=clang++
export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0
git fetch --tags
cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./
gcc --version
cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./
clang --version
make
- name: Run tests
run: ./test/etl_tests
build-clang-9-linux-stl-force-cpp03:
name: Clang-9 Linux - STL - Force C++03
build-clang-linux-stl-force-cpp03:
name: Clang Linux - STL - Force C++03
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2
@ -71,9 +69,9 @@ jobs:
- name: Build
run: |
sudo apt-get update
sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9"
export CC=clang-9
export CXX=clang++-9
sudo apt-get install -y "clang" "lldb" "lld" "clang-format"
export CC=clang
export CXX=clang++
export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0
git fetch --tags
cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=ON ./

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2
@ -32,7 +32,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2
@ -53,7 +53,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, ubuntu-20.04]
os: [ubuntu-20.04, ubuntu-22.04]
steps:
- uses: actions/checkout@v2

2
.gitignore vendored
View File

@ -363,8 +363,8 @@ examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvoptx
test/vs2022/.vs
test/vs2022/random_clcg.csv
test/vs2022/random_hash.csv
test/vs2022/random_lcg.csv
test/vs2022/random_lsfr.csv
test/vs2022/random_lcg.csv
test/vs2022/random_mwc.csv
test/vs2022/random_pcg.csv
test/vs2022/random_xorshift.csv

View File

@ -8,7 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/helpers.cmake)
set(MSG_PREFIX "etl |")
determine_version_with_git(${GIT_DIR_LOOKUP_POLICY})
if(NOT ETL_VERSION)
determine_version("version.txt")
determine_version_with_file("version.txt")
endif()
project(etl VERSION ${ETL_VERSION} LANGUAGES CXX)

View File

@ -14,6 +14,8 @@ Embedded Template Library (ETL)
[![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/ETLCPP)
[Project documentation](https://www.etlcpp.com/)
## Motivation
C++ is a great language to use for embedded applications and templates are a powerful aspect. The standard library can offer a great deal of well tested functionality, but there are some parts of the standard library that do not fit well with deterministic behaviour and limited resource requirements. These limitations usually preclude the use of dynamically allocated memory and containers with open ended sizes.

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library - Arduino",
"version": "20.35.8",
"version": "20.35.12",
"authors": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library - Arduino
version=20.35.8
version=20.35.12
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -1,4 +1,4 @@
function(determine_version VER_FILE_NAME)
function(determine_version_with_file VER_FILE_NAME)
file(READ ${VER_FILE_NAME} ETL_VERSION_RAW)
# Remove trailing whitespaces and/or newline
string(STRIP ${ETL_VERSION_RAW} ETL_VERSION)
@ -13,7 +13,11 @@ function(determine_version_with_git)
git_describe(VERSION ${ARGN})
string(FIND ${VERSION} "." VALID_VERSION)
if(VALID_VERSION EQUAL -1)
message(WARNING "Version string ${VERSION} retrieved with git describe is invalid")
if(PROJECT_IS_TOP_LEVEL)
# only warn if this is the top-level project, since we may be
# building from a tarball as a subproject
message(WARNING "Version string ${VERSION} retrieved with git describe is invalid")
endif()
return()
endif()
message(STATUS "${MSG_PREFIX} Version string determined with git describe: ${VERSION}")

View File

@ -34,6 +34,8 @@ SOFTWARE.
#include "platform.h"
#include "type_traits.h"
#include "static_assert.h"
#include "error_handler.h"
#include "exception.h"
#include <stdint.h>
@ -43,12 +45,68 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
/// Exception base for alignment
//***************************************************************************
class alignment_exception : public etl::exception
{
public:
alignment_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
/// Memory misalignment exception.
//***************************************************************************
class alignment_error : public alignment_exception
{
public:
alignment_error(string_type file_name_, numeric_type line_number_)
: alignment_exception(ETL_ERROR_TEXT("alignment:error", ETL_ALIGNMENT_FILE_ID"A"), file_name_, line_number_)
{
}
};
//*****************************************************************************
/// Check that 'p' has 'required_alignment'.
//*****************************************************************************
inline bool is_aligned(void* p, size_t required_alignment)
{
uintptr_t alignment = static_cast<uintptr_t>(required_alignment);
uintptr_t address = reinterpret_cast<uintptr_t>(p);
return (address % alignment) == 0U;
}
//*****************************************************************************
/// Check that 'p' has 'Alignment'.
//*****************************************************************************
template <size_t Alignment>
bool is_aligned(void* p)
{
uintptr_t address = reinterpret_cast<uintptr_t>(p);
return (address % static_cast<uintptr_t>(Alignment)) == 0U;
}
//*****************************************************************************
/// Check that 'p' has the alignment of 'T'.
//*****************************************************************************
template <typename T>
bool is_aligned(void* p)
{
return is_aligned<etl::alignment_of<T>::value>(p);
}
namespace private_alignment
{
//***************************************************************************
// Matcher.
//***************************************************************************
template <const bool IS_MATCH, const size_t ALIGNMENT, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
template <const bool IS_MATCH, const size_t ALIGNMENT, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
class type_with_alignment_matcher;
// Matching alignment.
@ -81,7 +139,8 @@ namespace etl
//***************************************************************************
// Helper.
//***************************************************************************
template <const size_t ALIGNMENT, typename T1, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
template <const size_t ALIGNMENT, typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
class type_with_alignment_helper
{
public:

View File

@ -2198,7 +2198,7 @@ namespace etl
return (nbits == etl::integral_limits<type>::bits) ? static_cast<T>(etl::integral_limits<type>::max)
: static_cast<T>((static_cast<type>(1U) << nbits) - 1U);
};
}
//***********************************
template <typename T, size_t NBits>
@ -2214,7 +2214,7 @@ namespace etl
ETL_CONSTEXPR T make_msb_mask(size_t nbits)
{
return static_cast<T>(etl::reverse_bits(make_lsb_mask<T>(nbits)));
};
}
//***************************************************************************
/// 8 bit binary byte constants.

View File

@ -51,33 +51,6 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
/// Exception base for byte streams
//***************************************************************************
class byte_stream_exception : public etl::exception
{
public:
byte_stream_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
///\ingroup string
/// String empty exception.
//***************************************************************************
class byte_stream_overflow : public etl::byte_stream_exception
{
public:
byte_stream_overflow(string_type file_name_, numeric_type line_number_)
: byte_stream_exception(ETL_ERROR_TEXT("byte_stream:overflow", ETL_BYTE_STREAM_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
/// Encodes a byte stream.
//***************************************************************************
@ -170,10 +143,6 @@ namespace etl
{
write_unchecked(value);
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
}
return success;
}
@ -201,10 +170,6 @@ namespace etl
{
write_unchecked(value);
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
}
return success;
}
@ -238,10 +203,6 @@ namespace etl
{
write_unchecked(range);
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
}
return success;
}
@ -273,10 +234,6 @@ namespace etl
{
write_unchecked(start, length);
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
}
return success;
}
@ -295,10 +252,6 @@ namespace etl
{
step(n * sizeof(T));
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
}
return success;
}
@ -749,14 +702,13 @@ namespace etl
template <typename T>
bool skip(size_t n)
{
if (n < available<T>())
if (n <= available<T>())
{
pcurrent += (n * sizeof(T));
return true;
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow));
return false;
}
}

View File

@ -70,6 +70,19 @@ namespace etl
}
};
//***************************************************************************
/// Incompatible type exception.
//***************************************************************************
class circular_buffer_incompatible_type : public circular_buffer_exception
{
public:
circular_buffer_incompatible_type(string_type file_name_, numeric_type line_number_)
: circular_buffer_exception(ETL_ERROR_TEXT("circular_buffer:type", ETL_CIRCULAR_BUFFER_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
///
//***************************************************************************
@ -962,6 +975,13 @@ namespace etl
etl::fill(begin(), end(), value);
}
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
virtual void repair() = 0;
#endif
//*************************************************************************
/// - operator for iterator
//*************************************************************************
@ -1037,6 +1057,14 @@ namespace etl
}
}
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair_buffer(T* pbuffer_)
{
pbuffer = pbuffer_;
}
pointer pbuffer;
private:
@ -1176,6 +1204,22 @@ namespace etl
this->clear();
}
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
virtual
#endif
void repair()
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
ETL_OVERRIDE
#endif
{
ETL_ASSERT(etl::is_trivially_copyable<T>::value, ETL_ERROR(etl::circular_buffer_incompatible_type));
etl::icircular_buffer<T>::repair_buffer(buffer);
}
private:
/// The uninitialised storage.
@ -1343,6 +1387,19 @@ namespace etl
{
this->clear();
}
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
virtual
#endif
void repair()
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
ETL_OVERRIDE
#endif
{
}
};
//*************************************************************************

View File

@ -67,6 +67,7 @@ SOFTWARE.
#include "crc16_usb.h"
#include "crc16_x25.h"
#include "crc16_xmodem.h"
#include "crc16_m17.h"
#include "crc32.h"
#include "crc32_bzip2.h"

78
include/etl/crc16_m17.h Normal file
View File

@ -0,0 +1,78 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_M17_INCLUDED
#define ETL_CRC16_M17_INCLUDED
#include "platform.h"
#include "private/crc_implementation.h"
///\defgroup crc16_m17 16 bit CRC calculation
///\ingroup crc
namespace etl
{
#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION)
template <size_t Table_Size>
using crc16_m17_t = etl::crc_type<etl::private_crc::crc16_m17_parameters, Table_Size>;
#else
template <size_t Table_Size>
class crc16_m17_t : public etl::crc_type<etl::private_crc::crc16_m17_parameters, Table_Size>
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_m17_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_m17_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
#endif
typedef etl::crc16_m17_t<256U> crc16_m17_t256;
typedef etl::crc16_m17_t<16U> crc16_m17_t16;
typedef etl::crc16_m17_t<4U> crc16_m17_t4;
typedef crc16_m17_t256 crc16_m17;
}
#endif

View File

@ -66,7 +66,7 @@ namespace etl
public:
//*************************************************************************
/// Constructor.
/// Default constructor.
/// The initial value is set to the first value.
//*************************************************************************
cyclic_value()
@ -74,6 +74,16 @@ namespace etl
{
}
//*************************************************************************
/// Constructor.
/// Set to an initial value.
/// Clamped to the range.
//*************************************************************************
explicit cyclic_value(T initial)
{
set(initial);
}
//*************************************************************************
/// Copy constructor.
//*************************************************************************
@ -340,10 +350,24 @@ namespace etl
cyclic_value(T first_, T last_)
: value(first_),
first_value(first_),
last_value(last_)
last_value(last_)
{
}
//*************************************************************************
/// Constructor.
/// Set to an initial value.
/// Clamped to the range.
///\param first The first value in the range.
///\param last The last value in the range.
//*************************************************************************
cyclic_value(T first_, T last_, T initial)
: first_value(first_)
, last_value(last_)
{
set(initial);
}
//*************************************************************************
/// Copy constructor.
//*************************************************************************

View File

@ -1742,7 +1742,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename ... Args>
void emplace_back(Args && ... args)
reference emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1752,6 +1752,7 @@ namespace etl
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
#else
@ -1761,7 +1762,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1>
void emplace_back(const T1& value1)
reference emplace_back(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1771,6 +1772,7 @@ namespace etl
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*************************************************************************
@ -1778,7 +1780,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2>
void emplace_back(const T1& value1, const T2& value2)
reference emplace_back(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1788,6 +1790,7 @@ namespace etl
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*************************************************************************
@ -1795,7 +1798,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_back(const T1& value1, const T2& value2, const T3& value3)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1805,6 +1808,7 @@ namespace etl
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*************************************************************************
@ -1812,7 +1816,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1822,6 +1826,7 @@ namespace etl
++_end;
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
#endif
@ -1870,7 +1875,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
reference emplace_front(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1880,6 +1885,7 @@ namespace etl
::new (&(*_begin)) T(etl::forward<Args>(args)...);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return front();
}
#else
@ -1889,7 +1895,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1>
void emplace_front(const T1& value1)
reference emplace_front(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1899,6 +1905,7 @@ namespace etl
::new (&(*_begin)) T(value1);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return front();
}
//*************************************************************************
@ -1906,7 +1913,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2>
void emplace_front(const T1& value1, const T2& value2)
reference emplace_front(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1916,6 +1923,7 @@ namespace etl
::new (&(*_begin)) T(value1, value2);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return front();
}
//*************************************************************************
@ -1923,7 +1931,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_front(const T1& value1, const T2& value2, const T3& value3)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1933,6 +1941,7 @@ namespace etl
::new (&(*_begin)) T(value1, value2, value3);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return front();
}
//*************************************************************************
@ -1940,7 +1949,7 @@ namespace etl
/// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(deque_full));
@ -1950,6 +1959,7 @@ namespace etl
::new (&(*_begin)) T(value1, value2, value3, value4);
++current_size;
ETL_INCREMENT_DEBUG_COUNT
return front();
}
#endif

View File

@ -31,12 +31,59 @@ SOFTWARE.
#ifndef ETL_EXPECTED_INCLUDED
#define ETL_EXPECTED_INCLUDED
///\defgroup expected expected
///\ingroup utilities
#include "platform.h"
#include "type_traits.h"
#include "exception.h"
#include "error_handler.h"
#include "utility.h"
#include "variant.h"
namespace etl
{
//***************************************************************************
/// Base exception for et::expected
//***************************************************************************
class expected_exception : public etl::exception
{
public:
expected_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
/// expected_invalid
//***************************************************************************
template <typename TError>
class expected_invalid;
//*******************************************
template<>
class expected_invalid<void> : public etl::expected_exception
{
public:
expected_invalid(string_type file_name_, numeric_type line_number_)
: expected_exception(ETL_ERROR_TEXT("expected:invalid", ETL_EXPECTED_FILE_ID"A"), file_name_, line_number_)
{
}
};
//*******************************************
template <typename TError>
class expected_invalid : etl::expected_invalid<void>
{
public:
expected_invalid(string_type file_name_, numeric_type line_number_)
: expected_invalid<void>(file_name_, line_number_)
{
}
};
//***************************************************************************
/// Unexpected type.
/// etl::unexpected represents an unexpected value stored in etl::expected.
@ -46,10 +93,12 @@ namespace etl
{
public:
typedef TError error_type;
//*******************************************
/// Copy constructor.
//*******************************************
ETL_CONSTEXPR14 unexpected(const unexpected& other)
ETL_CONSTEXPR unexpected(const unexpected& other)
: error_value(other.error_value)
{
}
@ -64,22 +113,23 @@ namespace etl
}
#endif
#if ETL_USING_CPP11
#if ETL_CPP11_SUPPORTED
//*******************************************
/// Construct from argument.
//*******************************************
template <typename TErr = TError, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::unexpected<TErr>>::value &&
template <typename TErr = TError, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, unexpected>::value &&
!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::in_place_t>::value, int>::type>
constexpr explicit unexpected(TErr&& e)
: error_value(etl::forward<TErr>(e))
{
}
#else
//*******************************************
/// Construct from argument.
//*******************************************
template <typename TErr>
explicit unexpected(const TErr& e, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::unexpected<TErr> >::value &&
explicit unexpected(const TErr& e, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, unexpected>::value &&
!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::in_place_t>::value, int>::type = 0)
: error_value(e)
{
@ -112,10 +162,11 @@ namespace etl
/// Assign from etl::unexpected.
//*******************************************
ETL_CONSTEXPR14
etl::unexpected<TError>& operator =(const etl::unexpected<TError>& rhs)
etl::unexpected<TError>& operator =(const etl::unexpected<TError>& rhs)
{
error_value = rhs.error_value;
ETL_STATIC_ASSERT(etl::is_copy_constructible<TError>::value, "Error not copy assignable");
error_value = rhs.error_value;
return *this;
}
@ -124,48 +175,16 @@ namespace etl
/// Move assign from etl::unexpected.
//*******************************************
ETL_CONSTEXPR14
etl::unexpected<TError>& operator =(etl::unexpected<TError>&& rhs)
etl::unexpected<TError>& operator =(etl::unexpected<TError>&& rhs)
{
error_value = etl::move(rhs.error_value);
ETL_STATIC_ASSERT(etl::is_move_constructible<TError>::value, "Error not move assignable");
error_value = etl::move(rhs.error_value);
return *this;
}
#endif
#if ETL_USING_CPP11
//*******************************************
/// Get the error.
//*******************************************
constexpr const TError& error() const& noexcept
{
return error_value;
}
//*******************************************
/// Get the error.
//*******************************************
constexpr const TError&& error() const&& noexcept
{
return etl::move(error_value);
}
#if ETL_USING_CPP14
//*******************************************
/// Get the error.
//*******************************************
constexpr TError& error() & noexcept
{
return error_value;
}
//*******************************************
/// Get the error.
//*******************************************
constexpr TError&& error() && noexcept
{
return etl::move(error_value);
}
#else
//*******************************************
/// Get the error.
//*******************************************
@ -174,6 +193,14 @@ namespace etl
return error_value;
}
//*******************************************
/// Get the error.
//*******************************************
constexpr const TError& error() const& noexcept
{
return error_value;
}
//*******************************************
/// Get the error.
//*******************************************
@ -181,8 +208,14 @@ namespace etl
{
return etl::move(error_value);
}
#endif
//*******************************************
/// Get the error.
//*******************************************
constexpr TError&& error() const&& noexcept
{
return etl::move(error_value);
}
#else
//*******************************************
/// Get the error.
@ -208,10 +241,662 @@ namespace etl
TError error_value;
};
//*****************************************************************************
/// unexpect_t
//*****************************************************************************
struct unexpect_t
{
ETL_CONSTEXPR14 explicit unexpect_t()
{
}
};
#if ETL_USING_CPP17
template <typename TError>
unexpected(TError) -> unexpected<TError>;
inline constexpr unexpect_t unexpect{};
#else
static const unexpect_t unexpect;
#endif
//*****************************************************************************
/// Expected type.
//*****************************************************************************
template <typename TValue, typename TError>
class expected
{
public:
typedef etl::expected<TValue, TError> this_type;
typedef TValue value_type;
typedef TError error_type;
typedef etl::unexpected<TError> unexpected_type;
#if ETL_USING_CPP11
template <typename U>
using rebind = expected<U, TError>;
#endif
//*******************************************
/// Default constructor
//*******************************************
ETL_CONSTEXPR14 expected() ETL_NOEXCEPT
: storage(etl::in_place_index_t<Value_Type>(), value_type())
{
}
//*******************************************
/// Constructor
//*******************************************
ETL_CONSTEXPR14 expected(const value_type& value_) ETL_NOEXCEPT
: storage(etl::in_place_index_t<Value_Type>(), value_)
{
}
#if ETL_USING_CPP11
//*******************************************
/// Constructor
//*******************************************
ETL_CONSTEXPR14 expected(value_type&& value_) ETL_NOEXCEPT
: storage(etl::in_place_index_t<Value_Type>(), etl::move(value_))
{
}
#endif
//*******************************************
/// Copy constructor
//*******************************************
ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT
: storage(other.storage)
{
}
#if ETL_USING_CPP11
//*******************************************
/// Move constructor
//*******************************************
ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT
: storage(etl::move(other.storage))
{
}
#endif
//*******************************************
/// Copy construct from unexpected type.
//*******************************************
template <typename F>
ETL_CONSTEXPR14 explicit expected(const etl::unexpected<F>& ue)
: storage(etl::in_place_index_t<Error_Type>(), ue.error())
{
}
#if ETL_USING_CPP11
//*******************************************
/// Move construct from unexpected type.
//*******************************************
template <typename F>
ETL_CONSTEXPR14 explicit expected(etl::unexpected<F>&& ue)
: storage(etl::in_place_index_t<Error_Type>(), etl::move(ue.error()))
{
}
#endif
//*******************************************
/// Construct with default value type.
//*******************************************
ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT
: storage(value_type())
{
}
#if ETL_USING_CPP11
//*******************************************
/// Construct value type from arguments.
//*******************************************
template <typename... Args>
ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args)
: storage(etl::forward<Args>(args)...)
{
}
//*******************************************
/// Construct value type from initializser_list and arguments.
//*******************************************
template <typename U, typename... Args>
ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list<U> il, Args&&... args)
: storage(il, etl::forward<Args>(args)...)
{
}
//*******************************************
/// Construct error type from arguments.
//*******************************************
template <typename... Args>
ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args)
: storage(error_type(etl::forward<Args>(args)...))
{
}
#if ETL_HAS_INITIALIZER_LIST
//*******************************************
/// Construct error type from initializser_list and arguments.
//*******************************************
template <typename U, typename... Args>
ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list<U> il, Args&&... args)
: storage(error_type(il, etl::forward<Args>(args)...))
{
}
#endif
#endif
//*******************************************
///
//*******************************************
this_type& operator =(const this_type& other)
{
ETL_STATIC_ASSERT(etl::is_copy_constructible<TValue>::value && etl::is_copy_constructible<TError>::value, "Not copy assignable");
storage = other.storage;
return *this;
}
#if ETL_USING_CPP11
//*******************************************
///
//*******************************************
this_type& operator =(this_type&& other)
{
ETL_STATIC_ASSERT(etl::is_move_constructible<TValue>::value && etl::is_move_constructible<TError>::value, "Not move assignable");
storage = etl::move(other.storage);
return *this;
}
#endif
//*******************************************
/// Copy assign from value
//*******************************************
expected& operator =(const value_type& value)
{
ETL_STATIC_ASSERT(etl::is_copy_constructible<TValue>::value, "Value not copy assignable");
storage.template emplace<Value_Type>(value);
return *this;
}
#if ETL_USING_CPP11
//*******************************************
/// Move assign from value
//*******************************************
expected& operator =(value_type&& value)
{
ETL_STATIC_ASSERT(etl::is_move_constructible<TValue>::value, "Value not move assignable");
storage.template emplace<Value_Type>(etl::move(value));
return *this;
}
#endif
//*******************************************
/// Copy assign from error
//*******************************************
expected& operator =(const unexpected_type& error)
{
ETL_STATIC_ASSERT(etl::is_copy_constructible<TError>::value, "Error not copy assignable");
storage.template emplace<Error_Type>(error);
return *this;
}
#if ETL_USING_CPP11
//*******************************************
/// Move assign from error
//*******************************************
expected& operator =(unexpected_type&& error)
{
ETL_STATIC_ASSERT(etl::is_move_constructible<TError>::value, "Error not move assignable");
storage.template emplace<Error_Type>(etl::move(error));
return *this;
}
#endif
#if ETL_USING_CPP11
//*******************************************
/// Get the value.
//*******************************************
ETL_CONSTEXPR14 value_type& value()&
{
return etl::get<Value_Type>(storage);
}
//*******************************************
/// Get the value.
//*******************************************
ETL_CONSTEXPR14 const value_type& value() const&
{
return etl::get<Value_Type>(storage);
}
//*******************************************
/// Get the value.
//*******************************************
ETL_CONSTEXPR14 value_type&& value()&&
{
return etl::move(etl::get<Value_Type>(storage));
}
//*******************************************
/// Get the value.
//*******************************************
ETL_CONSTEXPR14 const value_type&& value() const&&
{
return etl::move(etl::get<Value_Type>(storage));
}
#else
//*******************************************
/// Get the value.
//*******************************************
value_type& value() const
{
return etl::get<Value_Type>(storage);
}
#endif
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool has_value() const
{
return (storage.index() == Value_Type);
}
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
operator bool() const
{
return has_value();
}
#if ETL_USING_CPP11
//*******************************************
///
//*******************************************
template <typename U>
ETL_NODISCARD
ETL_CONSTEXPR14
value_type value_or(U&& default_value) const&
{
if (has_value())
{
return value();
}
else
{
return default_value;
}
}
//*******************************************
///
//*******************************************
template <typename U>
ETL_NODISCARD
ETL_CONSTEXPR14
value_type value_or(U&& default_value)&&
{
if (has_value())
{
return etl::move(value());
}
else
{
return etl::move(default_value);
}
}
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
error_type& error()& ETL_NOEXCEPT
{
return etl::get<Error_Type>(storage);
}
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
const error_type& error() const& ETL_NOEXCEPT
{
return etl::get<Error_Type>(storage);
}
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
error_type&& error() && ETL_NOEXCEPT
{
return etl::move(etl::get<Error_Type>(storage));
}
//*******************************************
///
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
const error_type&& error() const&& ETL_NOEXCEPT
{
return etl::move(etl::get<Error_Type>(storage));
}
//*******************************************
///
//*******************************************
template <typename... Args>
ETL_CONSTEXPR14 value_type& emplace(Args&&... args) ETL_NOEXCEPT
{
storage.emplace(args...);
}
//*******************************************
///
//*******************************************
template <typename U, typename... Args>
ETL_CONSTEXPR14 value_type& emplace(std::initializer_list<U>& il, Args&&... args) ETL_NOEXCEPT
{
storage.emplace(il, args...);
}
#else
//*******************************************
///
//*******************************************
template <typename U>
value_type value_or(const U& default_value) const
{
if (has_value())
{
return value();
}
else
{
return default_value;
}
}
//*******************************************
///
//*******************************************
error_type& error() const
{
return etl::get<Error_Type>(storage);
}
#endif
//*******************************************
///
//*******************************************
value_type* operator ->()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid<TError>));
#endif
return etl::addressof(etl::get<value_type>(storage));
}
//*******************************************
///
//*******************************************
const value_type* operator ->() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid<TError>));
#endif
return etl::addressof(etl::get<value_type>(storage));
}
//*******************************************
///
//*******************************************
value_type& operator *()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid<TError>));
#endif
return etl::get<value_type>(storage);
}
//*******************************************
///
//*******************************************
const value_type& operator *() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid<TError>));
#endif
return etl::get<value_type>(storage);
}
private:
enum
{
Uninitialised,
Value_Type,
Error_Type
};
typedef etl::variant<etl::monostate, value_type, error_type> storage_type;
storage_type storage;
};
//*****************************************************************************
/// Specialisation for void value type.
//*****************************************************************************
template<typename TError>
class expected<void, TError>
{
public:
typedef etl::expected<void, TError> this_type;
typedef void value_type;
typedef TError error_type;
typedef etl::unexpected<TError> unexpected_type;
//*******************************************
/// Default constructor
//*******************************************
ETL_CONSTEXPR14
expected()
{
}
//*******************************************
/// Copy construct from unexpected
//*******************************************
ETL_CONSTEXPR14
expected(const unexpected_type& ue_)
: storage(ue_.error())
{
}
#if ETL_USING_CPP11
//*******************************************
/// Move construct from unexpected
//*******************************************
ETL_CONSTEXPR14
expected(unexpected_type&& ue_)
: storage(etl::move(ue_.error()))
{
}
#endif
//*******************************************
/// Copy construct
//*******************************************
ETL_CONSTEXPR14
expected(const this_type& other)
: storage(other.storage)
{
}
#if ETL_USING_CPP11
//*******************************************
/// Move construct
//*******************************************
ETL_CONSTEXPR14
expected(this_type&& other)
: storage(etl::move(other.storage))
{
}
#endif
//*******************************************
/// Copy assign
//*******************************************
this_type& operator =(const this_type& other)
{
ETL_STATIC_ASSERT(etl::is_copy_constructible<TError>::value, "Not copy assignable");
storage = other.storage;
return *this;
}
#if ETL_USING_CPP11
//*******************************************
/// Move assign
//*******************************************
this_type& operator =(this_type&& other)
{
ETL_STATIC_ASSERT(etl::is_move_constructible<TError>::value, "Not move assignable");
storage = etl::move(other.storage);
return *this;
}
#endif
//*******************************************
/// Copy assign from error
//*******************************************
expected& operator =(const unexpected_type& error)
{
ETL_STATIC_ASSERT(etl::is_copy_constructible<TError>::value, "Error not copy assignable");
storage.template emplace<Error_Type>(error);
return *this;
}
#if ETL_USING_CPP11
//*******************************************
/// Move assign from error
//*******************************************
expected& operator =(unexpected_type&& error)
{
ETL_STATIC_ASSERT(etl::is_move_constructible<TError>::value, "Error not move assignable");
storage.template emplace<Error_Type>(etl::move(error));
return *this;
}
#endif
//*******************************************
/// Returns true if expected has a value
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool has_value() const
{
return (storage.index() != Error_Type);
}
//*******************************************
/// Returns true if expected has a value
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
operator bool() const
{
return has_value();
}
#if ETL_USING_CPP11
//*******************************************
/// Returns the error
/// Undefined behaviour if an error has not been set.
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
error_type& error()& ETL_NOEXCEPT
{
return etl::get<Error_Type>(storage);
}
//*******************************************
/// Returns the error
/// Undefined behaviour if an error has not been set.
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
const error_type& error() const& ETL_NOEXCEPT
{
return etl::get<Error_Type>(storage);
}
//*******************************************
/// Returns the error
/// Undefined behaviour if an error has not been set.
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
error_type&& error() && ETL_NOEXCEPT
{
return etl::move(etl::get<Error_Type>(storage));
}
//*******************************************
/// Returns the error
/// Undefined behaviour if an error has not been set.
//*******************************************
ETL_NODISCARD
ETL_CONSTEXPR14
const error_type&& error() const&& ETL_NOEXCEPT
{
return etl::move(etl::get<Error_Type>(storage));
}
#else
//*******************************************
/// Returns the error
/// Undefined behaviour if an error has not been set.
//*******************************************
error_type& error() const
{
return etl::get<Error_Type>(storage);
}
#endif
private:
enum
{
Uninitialised,
Error_Type
};
etl::variant<etl::monostate, error_type> storage;
};
}
//*******************************************
@ -234,20 +919,5 @@ void swap(etl::unexpected<TError>& lhs, etl::unexpected<TError>& rhs)
lhs.swap(rhs);
}
//*****************************************************************************
/// unexpect_t
//*****************************************************************************
struct unexpect_t
{
ETL_CONSTEXPR14 explicit unexpect_t()
{
}
};
#if ETL_CPP17_SUPPORTED
inline constexpr unexpect_t unexpect{};
#else
static const unexpect_t unexpect;
#endif
#endif

View File

@ -100,5 +100,7 @@ SOFTWARE.
#define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67"
#define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68"
#define ETL_TO_ARITHMETIC_FILE_ID "69"
#define ETL_EXPECTED_FILE_ID "70"
#define ETL_ALIGNMENT_FILE_ID "71"
#endif

View File

@ -722,7 +722,7 @@ namespace etl
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
reference emplace_front(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
@ -731,13 +731,14 @@ namespace etl
::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
return front();
}
#else
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename T1>
void emplace_front(const T1& value1)
reference emplace_front(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
@ -746,13 +747,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename T1, typename T2>
void emplace_front(const T1& value1, const T2& value2)
reference emplace_front(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
@ -761,13 +763,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_front(const T1& value1, const T2& value2, const T3& value3)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
@ -776,13 +779,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list..
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(forward_list_full));
@ -791,6 +795,7 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3, value4);
ETL_INCREMENT_DEBUG_COUNT
insert_node_after(start_node, *p_data_node);
return front();
}
#endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
@ -1756,7 +1761,7 @@ namespace etl
//*************************************************************************
#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
constexpr auto make_forward_list(T... t) -> etl::forward_list<typename etl::common_type_t<T...>, sizeof...(T)>
constexpr auto make_forward_list(T&&... t) -> etl::forward_list<typename etl::common_type_t<T...>, sizeof...(T)>
{
return { { etl::forward<T>(t)... } };
}

View File

@ -346,7 +346,7 @@ namespace etl
/// Subsequent calls will do nothing.
///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true.
//*******************************************
void start(bool call_on_enter_state = true)
virtual void start(bool call_on_enter_state = true)
{
// Can only be started once.
if (p_state == ETL_NULLPTR)
@ -451,7 +451,7 @@ namespace etl
/// Reset the FSM to pre-started state.
///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false.
//*******************************************
void reset(bool call_on_exit_state = false)
virtual void reset(bool call_on_exit_state = false)
{
if ((p_state != ETL_NULLPTR) && call_on_exit_state)
{

View File

@ -372,7 +372,7 @@ namespace etl
/// Subsequent calls will do nothing.
///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true.
//*******************************************
void start(bool call_on_enter_state = true)
virtual void start(bool call_on_enter_state = true)
{
// Can only be started once.
if (p_state == ETL_NULLPTR)
@ -477,7 +477,7 @@ namespace etl
/// Reset the FSM to pre-started state.
///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false.
//*******************************************
void reset(bool call_on_exit_state = false)
virtual void reset(bool call_on_exit_state = false)
{
if ((p_state != ETL_NULLPTR) && call_on_exit_state)
{

View File

@ -50,6 +50,41 @@ namespace etl
{
}
//*******************************************
/// Starts the HFSM.
/// Can only be called once.
/// Subsequent calls will do nothing.
///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true.
//*******************************************
void start(bool call_on_enter_state = true) ETL_OVERRIDE
{
// Can only be started once.
if (p_state == ETL_NULLPTR)
{
p_state = state_list[0];
ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
if (call_on_enter_state)
{
do_enters(ETL_NULLPTR, p_state, true);
}
}
}
//*******************************************
/// Reset the HFSM to pre-started state.
///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false.
//*******************************************
virtual void reset(bool call_on_exit_state = false) ETL_OVERRIDE
{
if ((p_state != ETL_NULLPTR) && call_on_exit_state)
{
do_exits(ETL_NULLPTR, p_state);
}
p_state = ETL_NULLPTR;
}
using fsm::receive;
//*******************************************

View File

@ -782,10 +782,11 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename ... Args>
void emplace_back(Args && ... args)
reference emplace_back(Args && ... args)
{
T* p = storage.create<T>(etl::forward<Args>(args)...);
lookup.push_back(p);
return back();
}
#else
//*********************************************************************
@ -794,10 +795,11 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1>
void emplace_back(const T1& value1)
reference emplace_back(const T1& value1)
{
T* p = storage.create<T>(T(value1));
lookup.push_back(p);
return back();
}
//*********************************************************************
@ -806,10 +808,11 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2>
void emplace_back(const T1& value1, const T2& value2)
reference emplace_back(const T1& value1, const T2& value2)
{
T* p = storage.create<T>(T(value1, value2));
lookup.push_back(p);
return back();
}
//*********************************************************************
@ -818,10 +821,11 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2, typename T3>
void emplace_back(const T1& value1, const T2& value2, const T3& value3)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
T* p = storage.create<T>(T(value1, value2, value3));
lookup.push_back(p);
return back();
}
//*********************************************************************
@ -830,10 +834,11 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
T* p = storage.create<T>(T(value1, value2, value3, value4));
lookup.push_back(p);
return back();
}
#endif
@ -1433,7 +1438,7 @@ namespace etl
//*************************************************************************
#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
constexpr auto make_indirect_vector(T... t) -> etl::indirect_vector<typename etl::common_type_t<T...>, sizeof...(T)>
constexpr auto make_indirect_vector(T&&... t) -> etl::indirect_vector<typename etl::common_type_t<T...>, sizeof...(T)>
{
return { { etl::forward<T>(t)... } };
}

View File

@ -862,7 +862,7 @@ namespace etl
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename ... Args>
void emplace_front(Args && ... args)
reference emplace_front(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -873,13 +873,14 @@ namespace etl
::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
return front();
}
#else
//*************************************************************************
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1>
void emplace_front(const T1& value1)
reference emplace_front(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -890,13 +891,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2>
void emplace_front(const T1& value1, const T2& value2)
reference emplace_front(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -907,13 +909,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace_front(const T1& value1, const T2& value2, const T3& value3)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -924,13 +927,14 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
return front();
}
//*************************************************************************
/// Emplaces a value to the front of the list.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -941,6 +945,7 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3, value4);
ETL_INCREMENT_DEBUG_COUNT
insert_node(get_head(), *p_data_node);
return front();
}
#endif
@ -985,7 +990,7 @@ namespace etl
//*************************************************************************
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
template <typename ... Args>
void emplace_back(Args && ... args)
reference emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -996,10 +1001,11 @@ namespace etl
::new (&(p_data_node->value)) T(etl::forward<Args>(args)...);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
return back();
}
#else
template <typename T1>
void emplace_back(const T1& value1)
reference emplace_back(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -1010,10 +1016,11 @@ namespace etl
::new (&(p_data_node->value)) T(value1);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
return back();
}
template <typename T1, typename T2>
void emplace_back(const T1& value1, const T2& value2)
reference emplace_back(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -1024,10 +1031,11 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
return back();
}
template <typename T1, typename T2, typename T3>
void emplace_back(const T1& value1, const T2& value2, const T3& value3)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -1038,10 +1046,11 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
return back();
}
template <typename T1, typename T2, typename T3, typename T4>
void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!full(), ETL_ERROR(list_full));
@ -1052,6 +1061,7 @@ namespace etl
::new (&(p_data_node->value)) T(value1, value2, value3, value4);
ETL_INCREMENT_DEBUG_COUNT
insert_node(terminal_node, *p_data_node);
return back();
}
#endif

View File

@ -2450,6 +2450,103 @@ namespace etl
return (result == 0U) ? reinterpret_cast<const char*>(sb + n) : reinterpret_cast<const char*>(result);
}
#if ETL_USING_CPP11
//*****************************************************************************
/// Move construct the container at 'p'.
//*****************************************************************************
template <typename TObject>
TObject& construct_object_at(void* p, TObject&& other)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
return *etl::construct_at(reinterpret_cast<typename etl::remove_reference<TObject>::type*>(p), etl::forward<TObject>(other));
}
//*****************************************************************************
/// Construct the container at 'p' from arguments.
//*****************************************************************************
template <typename TObject, typename... TArgs>
TObject& construct_object_at(void* p, TArgs&&... args)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
return *etl::construct_at(reinterpret_cast<TObject*>(p), etl::forward<TArgs>(args)...);
}
#else
//*****************************************************************************
/// Default construct the container at 'p'.
//*****************************************************************************
template <typename TObject>
TObject& construct_object_at(void* p)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
return *etl::construct_at(reinterpret_cast<TObject*>(p));
}
//*****************************************************************************
/// Copy construct the container at 'p'.
//*****************************************************************************
template <typename TObject>
TObject& construct_object_at(void* p, const TObject& other)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
return *etl::construct_at(reinterpret_cast<TObject*>(p), other);
}
//*****************************************************************************
/// Construct the container at 'p' from argument.
//*****************************************************************************
template <typename TObject, typename TArg>
TObject& construct_object_at(void* p, const TArg& arg)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
return *etl::construct_at(reinterpret_cast<TObject*>(p), arg);
}
#endif
//*****************************************************************************
/// Get the container at 'p'.
//*****************************************************************************
template <typename TObject>
TObject& get_object_at(void* p)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
TObject& v = *reinterpret_cast<TObject*>(p);
return v;
}
//*****************************************************************************
/// Destroy the container at 'p'.
/// For a container that contains a type that is not trivially destructible.
//*****************************************************************************
template <typename TObject>
void destroy_object_at(void* p)
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(is_aligned<TObject>(p), ETL_ERROR(alignment_error));
#endif
TObject& v = get_object_at<TObject>(p);
v.~TObject();
}
}
#endif

View File

@ -184,6 +184,18 @@ namespace etl
//*******************************************
virtual void receive(const etl::imessage& msg) ETL_OVERRIDE
{
receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, msg);
}
virtual void receive(etl::shared_message shared_msg) ETL_OVERRIDE
{
receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, shared_msg);
}
//*******************************************
virtual void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& msg) ETL_OVERRIDE
{
const etl::message_id_t id = msg.get_message_id();
@ -200,7 +212,13 @@ namespace etl
if (itr != message_ids.end())
{
sub->get_router()->receive(msg);
etl::imessage_router* router = sub->get_router();
if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS ||
destination_router_id == router->get_message_router_id())
{
router->receive(msg);
}
}
sub = sub->next_subscription();
@ -212,12 +230,13 @@ namespace etl
{
etl::imessage_router& successor = get_successor();
successor.receive(msg);
successor.receive(destination_router_id, msg);
}
}
//*******************************************
virtual void receive(etl::shared_message shared_msg) ETL_OVERRIDE
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg) ETL_OVERRIDE
{
const etl::message_id_t id = shared_msg.get_message().get_message_id();
@ -234,7 +253,13 @@ namespace etl
if (itr != message_ids.end())
{
sub->get_router()->receive(shared_msg);
etl::imessage_router* router = sub->get_router();
if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS ||
destination_router_id == router->get_message_router_id())
{
router->receive(shared_msg);
}
}
sub = sub->next_subscription();
@ -244,7 +269,7 @@ namespace etl
// Always pass the message on to a successor.
if (has_successor())
{
get_successor().receive(shared_msg);
get_successor().receive(destination_router_id, shared_msg);
}
}

View File

@ -155,85 +155,6 @@ namespace etl
receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, shared_msg);
}
//********************************************
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg) ETL_OVERRIDE
{
switch (destination_router_id)
{
//*****************************
// Broadcast to all routers.
case etl::imessage_router::ALL_MESSAGE_ROUTERS:
{
router_list_t::iterator irouter = router_list.begin();
// Broadcast to everyone.
while (irouter != router_list.end())
{
etl::imessage_router& router = **irouter;
if (router.accepts(shared_msg.get_message().get_message_id()))
{
router.receive(shared_msg);
}
++irouter;
}
break;
}
//*****************************
// Must be an addressed message.
default:
{
// Find routers with the id.
ETL_OR_STD::pair<router_list_t::iterator, router_list_t::iterator> range = etl::equal_range(router_list.begin(),
router_list.end(),
destination_router_id,
compare_router_id());
// Call all of them.
while (range.first != range.second)
{
if ((*(range.first))->accepts(shared_msg.get_message().get_message_id()))
{
(*(range.first))->receive(shared_msg);
}
++range.first;
}
// Do any message buses.
// These are always at the end of the list.
router_list_t::iterator irouter = etl::lower_bound(router_list.begin(),
router_list.end(),
etl::imessage_bus::MESSAGE_BUS,
compare_router_id());
while (irouter != router_list.end())
{
// So pass it on.
(*irouter)->receive(destination_router_id, shared_msg);
++irouter;
}
break;
}
}
if (has_successor())
{
etl::imessage_router& successor = get_successor();
if (successor.accepts(shared_msg.get_message().get_message_id()))
{
successor.receive(destination_router_id, shared_msg);
}
}
}
//*******************************************
virtual void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& message) ETL_OVERRIDE
@ -315,6 +236,85 @@ namespace etl
}
}
//********************************************
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg) ETL_OVERRIDE
{
switch (destination_router_id)
{
//*****************************
// Broadcast to all routers.
case etl::imessage_router::ALL_MESSAGE_ROUTERS:
{
router_list_t::iterator irouter = router_list.begin();
// Broadcast to everyone.
while (irouter != router_list.end())
{
etl::imessage_router& router = **irouter;
if (router.accepts(shared_msg.get_message().get_message_id()))
{
router.receive(shared_msg);
}
++irouter;
}
break;
}
//*****************************
// Must be an addressed message.
default:
{
// Find routers with the id.
ETL_OR_STD::pair<router_list_t::iterator, router_list_t::iterator> range = etl::equal_range(router_list.begin(),
router_list.end(),
destination_router_id,
compare_router_id());
// Call all of them.
while (range.first != range.second)
{
if ((*(range.first))->accepts(shared_msg.get_message().get_message_id()))
{
(*(range.first))->receive(shared_msg);
}
++range.first;
}
// Do any message buses.
// These are always at the end of the list.
router_list_t::iterator irouter = etl::lower_bound(router_list.begin(),
router_list.end(),
etl::imessage_bus::MESSAGE_BUS,
compare_router_id());
while (irouter != router_list.end())
{
// So pass it on.
(*irouter)->receive(destination_router_id, shared_msg);
++irouter;
}
break;
}
}
if (has_successor())
{
etl::imessage_router& successor = get_successor();
if (successor.accepts(shared_msg.get_message().get_message_id()))
{
successor.receive(destination_router_id, shared_msg);
}
}
}
using imessage_router::accepts;
//*******************************************

View File

@ -92,7 +92,7 @@ namespace etl
public:
optional_invalid(string_type file_name_, numeric_type line_number_)
: optional_exception("optional: invalid", file_name_, line_number_)
: optional_exception("optional:invalid", file_name_, line_number_)
{
}
};
@ -101,7 +101,7 @@ namespace etl
/// An optional type.
/// If the optional type is not initialised then a type is not constructed.
/// See http://en.cppreference.com/w/cpp/utility/optional
///\tparam The type to store.
///\tparam T The type to store.
///\ingroup utilities
//*****************************************************************************
template <typename T, bool is_pod = etl::is_pod<T>::value>
@ -414,7 +414,7 @@ namespace etl
/// 1 parameter.
//*************************************************************************
template <typename T1>
void emplace(const T1& value1)
T& emplace(const T1& value1)
{
if (has_value())
{
@ -430,7 +430,7 @@ namespace etl
/// 2 parameters.
//*************************************************************************
template <typename T1, typename T2>
void emplace(const T1& value1, const T2& value2)
T& emplace(const T1& value1, const T2& value2)
{
if (has_value())
{
@ -446,7 +446,7 @@ namespace etl
/// 3 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3>
void emplace(const T1& value1, const T2& value2, const T3& value3)
T& emplace(const T1& value1, const T2& value2, const T3& value3)
{
if (has_value())
{
@ -462,7 +462,7 @@ namespace etl
/// 4 parameters.
//*************************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
if (has_value())
{
@ -573,6 +573,8 @@ namespace etl
//*****************************************************************************
/// For POD types.
///\tparam T The type to store.
///\ingroup utilities
//*****************************************************************************
template <typename T>
class optional<T, true>

View File

@ -91,6 +91,7 @@ namespace etl
typedef crc_parameters<uint16_t, 0x1021U, 0x89ECU, 0x0000U, true> crc16_tms37157_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0xC6C6U, 0x0000U, true> crc16_a_parameters;
typedef crc_parameters<uint16_t, 0x8005U, 0x0000U, 0x0000U, true> crc16_arc_parameters;
typedef crc_parameters<uint16_t, 0x5935U, 0xFFFFU, 0x0000U, false> crc16_m17_parameters;
// 32 bit.
typedef crc_parameters<uint32_t, 0x04C11DB7UL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, true> crc32_parameters;

View File

@ -354,9 +354,11 @@ namespace etl
/// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
///\param value The value to add.
//*********************************************************************
void emplace_back(parameter_t value)
reference emplace_back(parameter_t value)
{
base_t::emplace_back(value);
return back();
}
//*************************************************************************

View File

@ -71,6 +71,14 @@ namespace etl
};
}
//***************************************************************************
/// Monostate for variants.
///\ingroup variant
//***************************************************************************
struct monostate
{
};
//***************************************************************************
/// Base exception for the variant class.
///\ingroup variant

View File

@ -227,7 +227,7 @@ namespace etl
default:
{
// This should never occur.
#if defined(ETL_IN_UNIT_TEST)
#if defined(ETL_DEBUG)
assert(false);
#endif
break;
@ -681,7 +681,7 @@ namespace etl
}
//***************************************************************************
/// Emplace with variadic constructor parameters.
/// Emplace by type with variadic constructor parameters.
//***************************************************************************
template <typename T, typename... TArgs>
T& emplace(TArgs&&... args)
@ -701,6 +701,27 @@ namespace etl
return *static_cast<T*>(data);
}
//***************************************************************************
/// Emplace by index with variadic constructor parameters.
//***************************************************************************
template <size_t Index, typename... TArgs>
typename etl::variant_alternative<Index, variant<TArgs...>>::type emplace(TArgs&&... args)
{
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
operation(private_variant::Destroy, data, nullptr);
construct_in_place_args<type>(data, etl::forward<TArgs>(args)...);
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
type_id = Index;
return *static_cast<type*>(data);
}
//***************************************************************************
/// Move assignment operator for type.
///\param value The value to assign.

View File

@ -36,6 +36,7 @@ SOFTWARE.
#include "platform.h"
#include "variant.h"
#include "optional.h"
#if ETL_CPP11_NOT_SUPPORTED
#if !defined(ETL_IN_UNIT_TEST)
@ -49,10 +50,13 @@ namespace etl
/// Result type.
//*****************************************************************************
template <typename TValue, typename TError>
class result
class ETL_DEPRECATED result
{
public:
typedef TValue value_type;
typedef TError error_type;
//*******************************************
/// Cannot be default constructed
//*******************************************
@ -66,6 +70,7 @@ namespace etl
{
}
#if ETL_CPP11_SUPPORTED
//*******************************************
/// Move constructor
//*******************************************
@ -73,6 +78,7 @@ namespace etl
: data(etl::move(other.data))
{
}
#endif
//*******************************************
// Construct from a value
@ -101,10 +107,12 @@ namespace etl
//*******************************************
/// Move construct from error
//*******************************************
#if ETL_CPP11_SUPPORTED
result(TError&& error)
: data(etl::move(error))
{
}
#endif
//*******************************************
/// Copy assign
@ -136,11 +144,13 @@ namespace etl
//*******************************************
/// Move assign from value
//*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TValue&& value)
{
data = etl::move(value);
return *this;
}
#endif
//*******************************************
/// Copy assign from error
@ -154,11 +164,13 @@ namespace etl
//*******************************************
/// Move assign from error
//*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TError&& error)
{
data = etl::move(error);
return *this;
}
#endif
//*******************************************
/// <b>true</b> if result contains a value
@ -173,7 +185,7 @@ namespace etl
//*******************************************
bool is_value() const
{
return (data.index() == 0U);
return has_value();
}
//*******************************************
@ -181,7 +193,7 @@ namespace etl
//*******************************************
bool is_error() const
{
return (data.index() == 1U);
return !has_value();
}
//*******************************************
@ -199,7 +211,7 @@ namespace etl
//*******************************************
TValue&& value()
{
return etl::move(etl::get<TValue>(etl::move(data)));
return etl::move(etl::get<TValue>(data));
}
//*******************************************
@ -215,10 +227,12 @@ namespace etl
/// Returns an rvalue reference to the error.
/// Undefined if the result does not contain an error.
//*******************************************
#if ETL_CPP11_SUPPORTED
TError&& error()
{
return etl::move(etl::get<TError>(etl::move(data)));
return etl::move(etl::get<TError>(data));
}
#endif
private:
@ -234,11 +248,13 @@ namespace etl
{
public:
typedef void value_type;
typedef TError error_type;
//*******************************************
/// Default Constructor
//*******************************************
result()
: err(TError())
{
}
@ -246,7 +262,7 @@ namespace etl
/// Copy constructor
//*******************************************
result(const result& other)
: err(other.err)
: data(other.data)
{
}
@ -254,50 +270,62 @@ namespace etl
/// Move constructor
//*******************************************
result(result&& other)
: err(etl::move(other.err))
: data(etl::move(other.data))
{
}
//*******************************************
/// Construct from error
//*******************************************
result(const TError& err_)
: err(err_)
result(const TError& error)
: data(error)
{
}
//*******************************************
/// Move construct from error
//*******************************************
result(TError&& err_)
: err(etl::move(err_))
#if ETL_CPP11_SUPPORTED
result(TError&& error)
: data(etl::move(error))
{
}
#endif
//*******************************************
/// Copy assign from error
//*******************************************
result& operator =(const TError& err_)
result& operator =(const TError& error)
{
err = err_;
data = error;
return *this;
}
//*******************************************
/// Move assign from error
//*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TError&& err_)
{
err = etl::move(err_);
data = etl::move(error);
return *this;
}
#endif
//*******************************************
/// <b>true</b> if result contains a value
//*******************************************
bool has_value() const
{
return !data.has_value();
}
//*******************************************
/// <b>true</b> if result contains a value
//*******************************************
bool is_value() const
{
return false;
return has_value();
}
//*******************************************
@ -305,7 +333,7 @@ namespace etl
//*******************************************
bool is_error() const
{
return true;
return !has_value();
}
//*******************************************
@ -314,23 +342,138 @@ namespace etl
//*******************************************
const TError& error() const
{
return err;
return data.value();
}
//*******************************************
/// Returns an rvalue reference to the error.
/// Undefined if the result does not contain an error.
//*******************************************
#if ETL_CPP11_SUPPORTED
TError&& error()
{
return etl::move(err);
return etl::move(data.value());
}
#endif
private:
TError err;
etl::optional<TError> data;
};
//*****************************************************************************
/// Result type.
/// Specialisation for void error type.
//*****************************************************************************
template<typename TValue>
class result<TValue, void>
{
public:
//*******************************************
/// Default Constructor
//*******************************************
result()
{
}
//*******************************************
/// Copy constructor
//*******************************************
result(const result& other)
: data(other.data)
{
}
//*******************************************
/// Move constructor
//*******************************************
result(result&& other)
: data(etl::move(other.data))
{
}
//*******************************************
/// Construct from error
//*******************************************
result(const TValue& value)
: data(value)
{
}
//*******************************************
/// Move construct from error
//*******************************************
result(TValue&& value)
: data(etl::move(value))
{
}
//*******************************************
/// Copy assign from error
//*******************************************
result& operator =(const TValue& value)
{
data = value;
return *this;
}
//*******************************************
/// Move assign from error
//*******************************************
result& operator =(TValue&& value)
{
data = etl::move(value);
return *this;
}
//*******************************************
/// <b>true</b> if result contains a value
//*******************************************
bool has_value() const
{
return data.has_value();
}
//*******************************************
/// <b>true</b> if result contains a value
//*******************************************
bool is_value() const
{
return has_value();
}
//*******************************************
/// <b>true</b> if result contains an error
//*******************************************
bool is_error() const
{
return !has_value();
}
//*******************************************
/// Returns a const reference to the error.
/// Undefined if the result does not contain an error.
//*******************************************
const TValue& value() const
{
return data.value();
}
//*******************************************
/// Returns an rvalue reference to the error.
/// Undefined if the result does not contain an error.
//*******************************************
TValue&& value()
{
return etl::move(data.value());
}
#endif
private:
etl::optional<TValue> data;
};
}
#endif
#endif
#endif

View File

@ -33,6 +33,7 @@ SOFTWARE.
#include "platform.h"
#include "iterator.h"
#include "algorithm.h"
#include "circular_iterator.h"
#include "nullptr.h"
#include "hash.h"
@ -345,6 +346,25 @@ namespace etl
return pbegin[i];
}
////*************************************************************************
///// Compare two spans for equality.
////*************************************************************************
//template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
//{
// return ((begin() == other.begin()) && (Extent == other.size())) ||
// etl::equal(begin(), end(), other.begin(), other.end());
//}
////*************************************************************************
///// Compare two spans for non-equality.
////*************************************************************************
//template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
//{
// return !(*this == other);
//}
//*************************************************************************
/// Obtains a span that is a view over the first COUNT elements of this span.
//*************************************************************************
@ -604,8 +624,8 @@ namespace etl
//*************************************************************************
template <typename U, size_t N>
ETL_CONSTEXPR span(const etl::span<U, N>& other) ETL_NOEXCEPT
: pbegin(other.begin())
, pend(other.begin() + N)
: pbegin(other.pbegin)
, pend(other.pend)
{
}
@ -731,6 +751,26 @@ namespace etl
return pbegin[i];
}
////*************************************************************************
///// Compare two spans for equality.
////*************************************************************************
//template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2>& other) const ETL_NOEXCEPT
//{
// return (empty() && other.empty()) ||
// ((begin() == other.begin()) && (end() == other.end())) ||
// etl::equal(begin(), end(), other.begin(), other.end());
//}
////*************************************************************************
///// Compare two spans for non-equality.
////*************************************************************************
//template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2>& other) const ETL_NOEXCEPT
//{
// return !(*this == other);
//}
//*************************************************************************
/// Obtains a span that is a view over the first COUNT elements of this span.
//*************************************************************************
@ -809,6 +849,46 @@ namespace etl
pointer pend;
};
//*************************************************************************
/// Compare two spans for equality.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
operator ==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size());
}
//*************************************************************************
/// Compare two spans for inequality.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
bool operator !=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//*************************************************************************
/// Equality function.
/// Performs a comparision of the range values.
/// Returns <b>true</b> if one of the following are <b>true</b>
/// 1. Both spans are empty.
/// 2. They both point to the same range of data.
/// 3. The values in the two ranges are equal.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
equal(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs)
{
return (lhs.empty() && rhs.empty()) ||
((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size())) ||
etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
//*************************************************************************
/// Template deduction guides.
//*************************************************************************
@ -833,7 +913,7 @@ namespace etl
span(const etl::array<T, N>&)
-> span<const T, N>;
#if ETL_USING_STL
#if ETL_USING_STL && ETL_USING_CPP11
template <typename T, size_t N>
span(std::array<T, N>&)
->span<T, N>;
@ -854,7 +934,7 @@ namespace etl
size_t operator()(const etl::span<T>& view) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
reinterpret_cast<const uint8_t*>(&view[view.size()]));
reinterpret_cast<const uint8_t*>(&view[view.size()]));
}
};
#endif

View File

@ -43,6 +43,19 @@ SOFTWARE.
namespace etl
{
#if ETL_USING_CPP11
inline namespace literals
{
inline namespace string_literals
{
constexpr etl::string_view operator ""_sv(const char* str, size_t length) noexcept
{
return etl::string_view{ str, length };
}
}
}
#endif
typedef etl::ibasic_string<char> istring;
//***************************************************************************

View File

@ -41,6 +41,19 @@ SOFTWARE.
namespace etl
{
#if ETL_USING_CPP11
inline namespace literals
{
inline namespace string_literals
{
constexpr etl::u16string_view operator ""_sv(const char16_t* str, size_t length) noexcept
{
return etl::u16string_view{ str, length };
}
}
}
#endif
typedef ibasic_string<char16_t> iu16string;
//***************************************************************************

View File

@ -41,6 +41,19 @@ SOFTWARE.
namespace etl
{
#if ETL_USING_CPP11
inline namespace literals
{
inline namespace string_literals
{
constexpr etl::u32string_view operator ""_sv(const char32_t* str, size_t length) noexcept
{
return etl::u32string_view{ str, length };
}
}
}
#endif
typedef ibasic_string<char32_t> iu32string;
//***************************************************************************

View File

@ -459,7 +459,7 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename ... Args>
void emplace_back(Args && ... args)
reference emplace_back(Args && ... args)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
@ -467,6 +467,7 @@ namespace etl
::new (p_end) T(etl::forward<Args>(args)...);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
#else
//*********************************************************************
@ -475,7 +476,7 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1>
void emplace_back(const T1& value1)
reference emplace_back(const T1& value1)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
@ -483,6 +484,7 @@ namespace etl
::new (p_end) T(value1);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*********************************************************************
@ -491,7 +493,7 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2>
void emplace_back(const T1& value1, const T2& value2)
reference emplace_back(const T1& value1, const T2& value2)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
@ -499,6 +501,7 @@ namespace etl
::new (p_end) T(value1, value2);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*********************************************************************
@ -507,7 +510,7 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2, typename T3>
void emplace_back(const T1& value1, const T2& value2, const T3& value3)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
@ -515,6 +518,7 @@ namespace etl
::new (p_end) T(value1, value2, value3);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
//*********************************************************************
@ -523,7 +527,7 @@ namespace etl
///\param value The value to add.
//*********************************************************************
template <typename T1, typename T2, typename T3, typename T4>
void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full));
@ -531,6 +535,7 @@ namespace etl
::new (p_end) T(value1, value2, value3, value4);
++p_end;
ETL_INCREMENT_DEBUG_COUNT
return back();
}
#endif
@ -1353,7 +1358,7 @@ namespace etl
//*************************************************************************
#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
constexpr auto make_vector(T... t) -> etl::vector<typename etl::common_type_t<T...>, sizeof...(T)>
constexpr auto make_vector(T&&... t) -> etl::vector<typename etl::common_type_t<T...>, sizeof...(T)>
{
return { { etl::forward<T>(t)... } };
}
@ -1509,9 +1514,6 @@ namespace etl
ETL_OVERRIDE
#endif
{
ETL_ASSERT(etl::is_trivially_copyable<T>::value, ETL_ERROR(etl::vector_incompatible_type));
etl::ivector<T>::repair_buffer(this->p_buffer);
}
};

View File

@ -40,7 +40,7 @@ SOFTWARE.
#define ETL_VERSION_MAJOR 20
#define ETL_VERSION_MINOR 35
#define ETL_VERSION_PATCH 8
#define ETL_VERSION_PATCH 12
#define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH)

View File

@ -41,6 +41,19 @@ SOFTWARE.
namespace etl
{
#if ETL_USING_CPP11
inline namespace literals
{
inline namespace string_literals
{
constexpr etl::wstring_view operator ""_sv(const wchar_t* str, size_t length) noexcept
{
return etl::wstring_view{ str, length };
}
}
}
#endif
typedef ibasic_string<wchar_t> iwstring;
//***************************************************************************

View File

@ -1,6 +1,6 @@
{
"name": "Embedded Template Library",
"version": "20.35.8",
"version": "20.35.12",
"authors": {
"name": "John Wellbelove",
"email": "john.wellbelove@etlcpp.com"

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=20.35.8
version=20.35.12
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
license=MIT

View File

@ -1,3 +1,40 @@
===============================================================================
20.35.12
#615 Addition of etl::expected
#649 Changed intrusive_list and intrusive_forward_list iterator constructor parameter from reference to pointer.
#667 etl::span copy constructor with original span with fixed extent causes pend iterator to be invalid
#668 byte_stream changes that add error exceptions have changed previous behaviour
#670 span equality operators
#672 HFSM-specific start() and reset()
Fixed span templated copy constructor
Added destination_router_id parameter overrides to receive() virtual functions
Added ""_sv string view operators
Added M17 CRC
Added repair() to etl::circular_buffer
Added etl::contruct_object_at, etl::get_object_at and etl::destroy_object_at
Added etl::is_aligned, etl::alignment_exception and etl::alignment_error
Removed unnecessary code in etl::vector_ext::repair()
Updated sanity check make files
C++03 compatibility improvements
===============================================================================
20.35.11
Added emplace by index to variant (variadic)
#660 byte_stream_reader::skip error
===============================================================================
20.35.10
#659 emplace member functions return reference to emplaced value
===============================================================================
20.35.9
#657 -Wpedantic-failure. Removed superfluous semicolons
#653 CMake - Don't warn on tag missing when subproject
#651 result<T, void> specialization
#650 Fix result<void, E> default ctor
Removed Ubuntu 18.04 from Github Actions
Added Ubuntu 22.04 to Github Actions
===============================================================================
20.35.8
#648 Improve is_constructible, is_copy_constructible, is_move_constructible for type traits with default definitions

View File

@ -59,6 +59,7 @@ add_executable(etl_tests
test_crc16_en13757.cpp
test_crc16_genibus.cpp
test_crc16_kermit.cpp
test_crc16_m17.cpp
test_crc16_maxim.cpp
test_crc16_mcrf4xx.cpp
test_crc16_modbus.cpp
@ -102,6 +103,7 @@ add_executable(etl_tests
test_error_handler.cpp
test_etl_traits.cpp
test_exception.cpp
test_expected.cpp
test_fixed_iterator.cpp
test_fixed_sized_memory_block_allocator.cpp
test_flags.cpp
@ -341,3 +343,4 @@ add_test(etl_unit_tests etl_tests)
add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)
set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17)

View File

@ -97,7 +97,7 @@
}) \
UNITTEST_MULTILINE_MACRO_END
#define UNITTEST_CHECK_FALSE_EQUAL(expected, actual) \
#define UNITTEST_CHECK_NOT_EQUAL(expected, actual) \
UNITTEST_MULTILINE_MACRO_BEGIN \
UNITTEST_IMPL_TRY \
({ \
@ -254,16 +254,16 @@
#define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX
#endif
#ifdef CHECK_FALSE_EQUAL
#error CHECK_FALSE_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL instead
#ifdef CHECK_NOT_EQUAL
#error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead
#else
#define CHECK_FALSE_EQUAL UNITTEST_CHECK_FALSE_EQUAL
#define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL
#endif
#ifdef CHECK_FALSE_EQUAL_HEX
#error CHECK_FALSE_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL_HEX instead
#ifdef CHECK_NOT_EQUAL_HEX
#error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead
#else
#define CHECK_FALSE_EQUAL_HEX UNITTEST_CHECK_FALSE_EQUAL_HEX
#define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX
#endif
#ifdef CHECK_CLOSE

View File

@ -37,6 +37,7 @@ SOFTWARE.
#define ETL_ISTRING_REPAIR_ENABLE
#define ETL_IVECTOR_REPAIR_ENABLE
#define ETL_IDEQUE_REPAIR_ENABLE
#define ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
#define ETL_IN_UNIT_TEST
#define ETL_DEBUG_COUNT
#define ETL_ARRAY_VIEW_IS_MUTABLE

View File

@ -88,6 +88,7 @@ target_sources(t98 PRIVATE etl_profile.h
../crc16_en13757.h.t.cpp
../crc16_genibus.h.t.cpp
../crc16_kermit.h.t.cpp
../crc16_m17.h.t.cpp
../crc16_maxim.h.t.cpp
../crc16_mcrf4xx.h.t.cpp
../crc16_modbus.h.t.cpp
@ -129,6 +130,7 @@ target_sources(t98 PRIVATE etl_profile.h
../enum_type.h.t.cpp
../error_handler.h.t.cpp
../exception.h.t.cpp
../expected.h.t.cpp
../factorial.h.t.cpp
../fibonacci.h.t.cpp
../file_error_numbers.h.t.cpp

View File

@ -88,6 +88,7 @@ target_sources(t11 PRIVATE etl_profile.h
../crc16_en13757.h.t.cpp
../crc16_genibus.h.t.cpp
../crc16_kermit.h.t.cpp
../crc16_m17.h.t.cpp
../crc16_maxim.h.t.cpp
../crc16_mcrf4xx.h.t.cpp
../crc16_modbus.h.t.cpp
@ -129,6 +130,7 @@ target_sources(t11 PRIVATE etl_profile.h
../enum_type.h.t.cpp
../error_handler.h.t.cpp
../exception.h.t.cpp
../expected.h.t.cpp
../factorial.h.t.cpp
../fibonacci.h.t.cpp
../file_error_numbers.h.t.cpp

View File

@ -88,6 +88,7 @@ target_sources(t14 PRIVATE etl_profile.h
../crc16_en13757.h.t.cpp
../crc16_genibus.h.t.cpp
../crc16_kermit.h.t.cpp
../crc16_m17.h.t.cpp
../crc16_maxim.h.t.cpp
../crc16_mcrf4xx.h.t.cpp
../crc16_modbus.h.t.cpp
@ -129,6 +130,7 @@ target_sources(t14 PRIVATE etl_profile.h
../enum_type.h.t.cpp
../error_handler.h.t.cpp
../exception.h.t.cpp
../expected.h.t.cpp
../factorial.h.t.cpp
../fibonacci.h.t.cpp
../file_error_numbers.h.t.cpp

View File

@ -88,6 +88,7 @@ target_sources(t17 PRIVATE etl_profile.h
../crc16_en13757.h.t.cpp
../crc16_genibus.h.t.cpp
../crc16_kermit.h.t.cpp
../crc16_m17.h.t.cpp
../crc16_maxim.h.t.cpp
../crc16_mcrf4xx.h.t.cpp
../crc16_modbus.h.t.cpp
@ -129,6 +130,7 @@ target_sources(t17 PRIVATE etl_profile.h
../enum_type.h.t.cpp
../error_handler.h.t.cpp
../exception.h.t.cpp
../expected.h.t.cpp
../factorial.h.t.cpp
../fibonacci.h.t.cpp
../file_error_numbers.h.t.cpp

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/crc16_m17.h>

View File

@ -0,0 +1,29 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include <etl/expected.h>

View File

@ -126,5 +126,22 @@ namespace
etl::aligned_storage<100, 8>::type data9;
f(static_cast<int>(data9));
}
//*************************************************************************
TEST(test_is_aligned_tests)
{
alignas(uint32_t) char buffer[2U * sizeof(uint32_t)];
char* p = buffer;
CHECK_TRUE(etl::is_aligned(p, std::alignment_of<uint32_t>()));
CHECK_TRUE(etl::is_aligned<alignof(uint32_t)>(p));
CHECK_TRUE(etl::is_aligned<uint32_t>(p));
++p;
CHECK_FALSE(etl::is_aligned(p, std::alignment_of<uint32_t>()));
CHECK_FALSE(etl::is_aligned<alignof(uint32_t)>(p));
CHECK_FALSE(etl::is_aligned<uint32_t>(p));
}
};
}

View File

@ -152,8 +152,8 @@ namespace
CHECK_EQUAL(sizeof(uint8_t) + sizeof(uint16_t), (std::distance(used_span.begin(), used_span.end())));
CHECK_EQUAL(std::size(storage) - sizeof(uint8_t) - sizeof(uint16_t), (std::distance(free_span.begin(), free_span.end())));
CHECK(writer.write(uint32_t(0x12345678U))); // 4 more written.
CHECK_THROW(writer.write(uint32_t(0x12345678U)), etl::byte_stream_overflow); // Can't write 4 more.
CHECK(writer.write(uint32_t(0x12345678U))); // 4 more written.
CHECK_FALSE(writer.write(uint32_t(0x12345678U))); // Can't write 4 more.
CHECK(!writer.empty());
CHECK(!writer.full());
@ -186,7 +186,7 @@ namespace
CHECK(byte_stream.write(false));
// One too many.
CHECK_THROW(byte_stream.write(true), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(true));
CHECK_ARRAY_EQUAL(result, storage, 8);
}
@ -207,7 +207,7 @@ namespace
}
// One too many.
CHECK_THROW(byte_stream.write(int8_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(int8_t(0)));
for (size_t i = 0; i < storage.size(); ++i)
{
@ -231,7 +231,7 @@ namespace
}
// One too many.
CHECK_THROW(byte_stream.write(uint8_t(0U)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(uint8_t(0U)));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -255,7 +255,7 @@ namespace
CHECK(byte_stream.write(int16_t(0xFFFF)));
// One too many.
CHECK_THROW(byte_stream.write(int16_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(int16_t(0)));
for (size_t i = 0; i < storage.size(); ++i)
{
@ -279,7 +279,7 @@ namespace
CHECK(byte_stream.write(uint16_t(0xFFFFU)));
// One too many.
CHECK_THROW(byte_stream.write(uint16_t(0U)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(uint16_t(0U)));
for (size_t i = 0; i < storage.size(); ++i)
{
@ -306,7 +306,7 @@ namespace
CHECK(byte_stream.write(int32_t(0xFFFFFFFF)));
// One too many.
CHECK_THROW(byte_stream.write(int32_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(int32_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -333,7 +333,7 @@ namespace
CHECK(byte_stream.write(uint32_t(0xFFFFFFFFU)));
// One too many.
CHECK_THROW(byte_stream.write(uint32_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(uint32_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -360,7 +360,7 @@ namespace
CHECK(byte_stream.write(int64_t(0xFFFFFFFFFFFFFFFF)));
// One too many.
CHECK_THROW(byte_stream.write(int64_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(int64_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -387,7 +387,7 @@ namespace
CHECK(byte_stream.write(uint64_t(0xFFFFFFFFFFFFFFFFU)));
// One too many.
CHECK_THROW(byte_stream.write(uint64_t(0)), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.write(uint64_t(0)));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -413,7 +413,7 @@ namespace
CHECK(byte_stream.write(int32_t(0x01020304)));
CHECK(byte_stream.skip<int32_t>(2));
CHECK(byte_stream.write(int32_t(0x05060708)));
CHECK_THROW(byte_stream.skip<int32_t>(1), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.skip<int32_t>(1));
for (size_t i = 0U; i < storage.size(); ++i)
{
@ -437,7 +437,7 @@ namespace
CHECK(result[0] = byte_stream.read<int32_t>());
CHECK(byte_stream.skip<int32_t>(2));
CHECK(result[3] = byte_stream.read<int32_t>());
CHECK_THROW(byte_stream.skip<int32_t>(2), etl::byte_stream_overflow);
CHECK_FALSE(byte_stream.skip<int32_t>(2));
for (size_t i = 0U; i < result.size(); ++i)
{
@ -1242,7 +1242,7 @@ namespace
reader.restart();
// Skip five int16_t (too many)
CHECK_THROW(reader.skip<int16_t>(5U), etl::byte_stream_overflow);
CHECK_FALSE(reader.skip<int16_t>(5U));
}
//*************************************************************************
@ -1333,5 +1333,15 @@ namespace
CHECK_EQUAL(expected[i], result[i]);
}
}
//*************************************************************************
TEST(read_byte_stream_skip)
{
etl::array<uint8_t, 4> data;
etl::byte_stream_reader r(data.begin(), data.size(), etl::endian::little);
CHECK_TRUE(r.skip<uint8_t>(4));
etl::optional<etl::span<const uint8_t>> result = r.read<uint8_t>(4);
CHECK_FALSE(result.has_value());
CHECK_TRUE(r.empty());
}
};
}

View File

@ -990,5 +990,79 @@ namespace
bool isEqual = std::equal(blank.begin(), blank.end(), data.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_memcpy_repair)
{
using CB = etl::circular_buffer<int, SIZE>;
std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
CB data(input.begin(), input.end());;
char buffer[sizeof(CB)];
memcpy(&buffer, (const void*)&data, sizeof(data));
CB& rdata(*reinterpret_cast<CB*>(buffer));
rdata.repair();
// Check that the memcpy'd vector is the same.
CHECK_EQUAL(data.size(), rdata.size());
CHECK(!rdata.empty());
CHECK(rdata.full());
bool is_equal = std::equal(rdata.begin(),
rdata.end(),
data.begin());
CHECK(is_equal);
// Modify the original and check that the memcpy'd vector is not the same.
std::reverse(data.begin(), data.end());
is_equal = std::equal(rdata.begin(),
rdata.end(),
data.begin());
CHECK(!is_equal);
}
//*************************************************************************
TEST(test_memcpy_repair_virtual)
{
using CB = etl::circular_buffer<int, SIZE>;
using ICB = etl::icircular_buffer<int>;
std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
CB data(input.begin(), input.end());;
char buffer[sizeof(CB)];
memcpy(&buffer, (const void*)&data, sizeof(data));
ICB& rdata(*reinterpret_cast<CB*>(buffer));
rdata.repair();
// Check that the memcpy'd vector is the same.
CHECK_EQUAL(data.size(), rdata.size());
CHECK(!rdata.empty());
CHECK(rdata.full());
bool is_equal = std::equal(rdata.begin(),
rdata.end(),
data.begin());
CHECK(is_equal);
// Modify the original and check that the memcpy'd vector is not the same.
std::reverse(data.begin(), data.end());
is_equal = std::equal(rdata.begin(),
rdata.end(),
data.begin());
CHECK(!is_equal);
}
};
}

263
test/test_crc16_m17.cpp Normal file
View File

@ -0,0 +1,263 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "unit_test_framework.h"
#include <iterator>
#include <string>
#include <vector>
#include <stdint.h>
#include "etl/crc16_m17.h"
//*****************************************************************************
// The results for these tests were created from https://crccalc.com/
//*****************************************************************************
namespace
{
SUITE(test_crc16_m17)
{
//*************************************************************************
// Table size 256
//*************************************************************************
TEST(test_crc16_m17)
{
std::string data("123456789");
uint16_t crc = etl::crc16_m17(data.begin(), data.end());
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_add_values)
{
std::string data("123456789");
etl::crc16_m17 crc_calculator;
for (size_t i = 0UL; i < data.size(); ++i)
{
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_add_range)
{
std::string data("123456789");
etl::crc16_m17 crc_calculator;
crc_calculator.add(data.begin(), data.end());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_add_range_via_iterator)
{
std::string data("123456789");
etl::crc16_m17 crc_calculator;
std::copy(data.begin(), data.end(), crc_calculator.input());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
uint16_t crc1 = etl::crc16_m17(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_m17((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16_m17(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
//*************************************************************************
// Table size 16
//*************************************************************************
TEST(test_crc16_m17_16)
{
std::string data("123456789");
uint16_t crc = etl::crc16_m17_t16(data.begin(), data.end());
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_16_add_values)
{
std::string data("123456789");
etl::crc16_m17_t16 crc_calculator;
for (size_t i = 0UL; i < data.size(); ++i)
{
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_16_add_range)
{
std::string data("123456789");
etl::crc16_m17_t16 crc_calculator;
crc_calculator.add(data.begin(), data.end());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_16_add_range_via_iterator)
{
std::string data("123456789");
etl::crc16_m17_t16 crc_calculator;
std::copy(data.begin(), data.end(), crc_calculator.input());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_16_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
uint16_t crc1 = etl::crc16_m17_t16(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_m17_t16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16_m17_t16(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
//*************************************************************************
// Table size 4
//*************************************************************************
TEST(test_crc16_m17_4)
{
std::string data("123456789");
uint16_t crc = etl::crc16_m17_t4(data.begin(), data.end());
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_4_add_values)
{
std::string data("123456789");
etl::crc16_m17_t4 crc_calculator;
for (size_t i = 0UL; i < data.size(); ++i)
{
crc_calculator.add(data[i]);
}
uint16_t crc = crc_calculator;
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_4_add_range)
{
std::string data("123456789");
etl::crc16_m17_t4 crc_calculator;
crc_calculator.add(data.begin(), data.end());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_4_add_range_via_iterator)
{
std::string data("123456789");
etl::crc16_m17_t4 crc_calculator;
std::copy(data.begin(), data.end(), crc_calculator.input());
uint16_t crc = crc_calculator.value();
CHECK_EQUAL(0x772BU, crc);
}
//*************************************************************************
TEST(test_crc16_m17_4_add_range_endian)
{
std::vector<uint8_t> data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U };
std::vector<uint32_t> data2 = { 0x04030201UL, 0x08070605UL };
std::vector<uint8_t> data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U };
uint16_t crc1 = etl::crc16_m17_t4(data1.begin(), data1.end());
uint16_t crc2 = etl::crc16_m17_t4((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size()));
CHECK_EQUAL(crc1, crc2);
uint16_t crc3 = etl::crc16_m17_t4(data3.rbegin(), data3.rend());
CHECK_EQUAL(crc1, crc3);
}
};
}

View File

@ -87,6 +87,24 @@ namespace
CHECK_EQUAL(value.last(), value.get());
}
//*************************************************************************
TEST(test_set_compile_time_initial_value_in_range)
{
etl::cyclic_value<int, 2, 7> value(5);
CHECK_EQUAL(5, value.get());
}
//*************************************************************************
TEST(test_set_compile_time_initial_value_out_of_range)
{
etl::cyclic_value<int, 2, 7> value1(1);
etl::cyclic_value<int, 2, 7> value2(8);
CHECK_EQUAL(2, value1.get());
CHECK_EQUAL(7, value2.get());
}
//*************************************************************************
TEST(test_set_run_time)
{
@ -108,6 +126,24 @@ namespace
CHECK_EQUAL(value.last(), value.get());
}
//*************************************************************************
TEST(test_set_run_time_initial_value_in_range)
{
etl::cyclic_value<int> value(2, 7, 5);
CHECK_EQUAL(5, value.get());
}
//*************************************************************************
TEST(test_set_run_time_initial_value_out_of_range)
{
etl::cyclic_value<int> value1(2, 7, 1);
etl::cyclic_value<int> value2(2, 7, 8);
CHECK_EQUAL(2, value1.get());
CHECK_EQUAL(7, value2.get());
}
//*************************************************************************
TEST(test_to_first_compile_time)
{

View File

@ -1490,6 +1490,16 @@ namespace
CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin()));
}
//*************************************************************************
TEST(test_emplace_back_return)
{
DataNDC data;
data.emplace_back("24");
auto& back = data.emplace_back("42");
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST(test_push_back_excess)
{
@ -1602,6 +1612,16 @@ namespace
CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin()));
}
//*************************************************************************
TEST(test_emplace_front_return)
{
DataNDC data;
data.emplace_front("24");
auto& front = data.emplace_front("42");
CHECK_EQUAL(front, data.front());
}
//*************************************************************************
TEST(test_push_front_excess)
{

448
test/test_expected.cpp Normal file
View File

@ -0,0 +1,448 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2022 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/expected.h"
#include "etl/type_traits.h"
#include <string>
#include <variant>
namespace
{
struct Value
{
std::string v;
Value()
{
}
Value(const std::string v_)
: v(v_)
{
}
operator std::string() const
{
return v;
}
};
struct ValueM
{
ValueM()
{
}
ValueM(const std::string& v_)
: v(v_)
{
}
ValueM(ValueM&&) = default;
ValueM& operator =(ValueM&&) = default;
ValueM(const ValueM&) = delete;
ValueM& operator =(const ValueM&) = delete;
std::string v;
};
struct Error
{
std::string e;
Error() = default;
Error(const Error&) = default;
Error& operator =(const Error&) = default;
Error(const std::string e_)
: e(e_)
{
}
Error& operator =(const std::string e_)
{
e = e_;
return *this;
}
operator std::string() const
{
return e;
}
};
struct ErrorM
{
ErrorM()
{
}
ErrorM(const std::string& e_)
: e(e_)
{
}
ErrorM(ErrorM&&) = default;
ErrorM& operator =(ErrorM&&) = default;
ErrorM(const ErrorM&) = delete;
ErrorM& operator =(const ErrorM&) = delete;
std::string e;
};
using Expected = etl::expected<Value, Error>;
using ExpectedV = etl::expected<void, Error>;
using ExpectedM = etl::expected<ValueM, ErrorM>;
using ExpectedVM = etl::expected<void, ErrorM>;
using Unexpected = etl::unexpected<Error>;
using UnexpectedV = etl::unexpected<Error>;
using UnexpectedM = etl::unexpected<ErrorM>;
}
namespace
{
SUITE(test_result)
{
//*************************************************************************
TEST(test_default_constructor)
{
Expected expected;
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
}
//*************************************************************************
TEST(test_constructor_for_result_with_value)
{
Value input = { "value 1" };
Expected expected(input);
Value output = expected.value();
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
CHECK_TRUE(output.v == input.v);
}
//*************************************************************************
TEST(test_constructor_for_const_result_with_value)
{
Value input = { "value 1" };
const Expected expected(input);
const Value& output = expected.value();
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
CHECK_TRUE(output.v == input.v);
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_with_value)
{
ValueM input = { "value 1" };
ExpectedM expected(etl::move(input));
ValueM output = etl::move(expected.value());
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
CHECK_TRUE(output.v == std::string("value 1"));
}
//*************************************************************************
TEST(test_constructor_for_result_with_error)
{
Error input = { "error 1" };
Unexpected unexpected(input);
Expected expected(unexpected);
Error output = expected.error();
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK(output.e == input.e);
}
//*************************************************************************
TEST(test_constructor_for_const_result_with_error)
{
const Error input = { "error 1" };
const Unexpected unexpected(input);
const Expected expected(unexpected);
const Error& output = expected.error();
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK(output.e == input.e);
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_with_error)
{
ErrorM input = { "error 1" };
UnexpectedM unexpected(etl::move(input));
ExpectedM expected(etl::move(unexpected));
ErrorM output = etl::move(expected.error());
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK_TRUE(output.e == std::string("error 1"));
}
//*************************************************************************
TEST(test_constructor_for_result_void_value_with_value)
{
ExpectedV expected;
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
}
//*************************************************************************
TEST(test_constructor_for_const_result_void_value_with_value)
{
const ExpectedV expected;
CHECK_TRUE(expected.has_value());
CHECK_TRUE(bool(expected));
}
//*************************************************************************
TEST(test_constructor_for_result_void_value_with_error)
{
Error input = { "error 1" };
UnexpectedV unexpected(input);
ExpectedV expected(unexpected);
Error output = expected.error();
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK_TRUE(output.e == input.e);
}
//*************************************************************************
TEST(test_constructor_for_const_result_void_value_with_error)
{
const Error input = { "error 1" };
const UnexpectedV unexpected(input);
const ExpectedV expected(unexpected);
const Error& output = expected.error();
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK_TRUE(output.e == input.e);
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_void_value_with_error)
{
ErrorM input = { "error 1" };
UnexpectedM unexpected(etl::move(input));
ExpectedM expected(etl::move(unexpected));
ErrorM output = etl::move(expected.error());
CHECK_FALSE(expected.has_value());
CHECK_FALSE(bool(expected));
CHECK(output.e == std::string("error 1"));
}
//*************************************************************************
TEST(test_copy_construct)
{
Value input1 = { "value 1" };
Expected expected1(input1);
Expected expected2(expected1);
Value output1 = expected2.value();
CHECK_TRUE(expected1.has_value());
CHECK_TRUE(expected2.has_value());
CHECK(output1.v == input1.v);
}
//*************************************************************************
TEST(test_copy_assign)
{
Value input1 = { "value 1" };
Expected expected1(input1);
Value input2 = { "value 2" };
Expected expected2(input2);
expected2 = expected1;
Value output1 = expected1.value();
Value output2 = expected2.value();
CHECK_TRUE(expected1.has_value());
CHECK_TRUE(expected2.has_value());
//CHECK(output1.v != input1.v);
//CHECK(output2.v != input1.v);
//CHECK(output1.v == input2.v);
//CHECK(output2.v == input2.v);
}
//*************************************************************************
TEST(test_move_construct)
{
ValueM input1 = { "value 1" };
ExpectedM expected1(etl::move(input1));
ExpectedM expected2(etl::move(expected1));
ValueM output1 = etl::move(expected1.value());
ValueM output2 = etl::move(expected2.value());
CHECK_TRUE(expected1.has_value());
CHECK_TRUE(expected2.has_value());
CHECK_EQUAL("", output1.v);
CHECK_EQUAL("value 1", output2.v);
}
//*************************************************************************
TEST(test_move_assign)
{
ValueM input1 = { "value 1" };
ExpectedM expected1(etl::move(input1));
ValueM input2 = { "value 2" };
ExpectedM expected2(etl::move(input2));
expected2 = etl::move(expected1);
ValueM output1 = etl::move(expected1.value());
ValueM output2 = etl::move(expected2.value());
CHECK_TRUE(expected1.has_value());
CHECK_TRUE(expected2.has_value());
CHECK_EQUAL("", output1.v);
CHECK_EQUAL("value 1", output2.v);
}
//*************************************************************************
TEST(test_copy_construct_void_value)
{
Error input1 = { "error 1" };
UnexpectedV unexpected1(input1);
ExpectedV expected1(unexpected1);
ExpectedV expected2(expected1);
CHECK_FALSE(expected1.has_value());
CHECK_FALSE(expected2.has_value());
Error output1 = expected1.error();
Error output2 = expected2.error();
CHECK_EQUAL(input1.e, output1.e);
CHECK_EQUAL(input1.e, output2.e);
}
//*************************************************************************
TEST(test_copy_assign_void_value)
{
Error input1 = { "error 1" };
UnexpectedV unexpected1(input1);
Error input2 = { "error 2" };
UnexpectedV unexpected2(input2);
ExpectedV expected1(unexpected1);
ExpectedV expected2(unexpected2);
expected2 = expected1;
Error output1 = expected1.error();
Error output2 = expected2.error();
CHECK_FALSE(expected1.has_value());
CHECK_FALSE(expected2.has_value());
CHECK_EQUAL(input1.e, output1.e);
CHECK_EQUAL(input1.e, output2.e);
}
//*************************************************************************
TEST(test_move_construct_void_value)
{
ErrorM input1 = { "error 1" };
UnexpectedM unexpected1(etl::move(input1));
ExpectedVM expected1(etl::move(unexpected1));
ExpectedVM expected2(etl::move(expected1));
ErrorM output1 = etl::move(expected1.error());
ErrorM output2 = etl::move(expected2.error());
CHECK_FALSE(expected1.has_value());
CHECK_FALSE(expected2.has_value());
CHECK_EQUAL("", output1.e);
CHECK_EQUAL("error 1", output2.e);
}
//*************************************************************************
TEST(test_move_assign_void_value)
{
ErrorM input1 = { "error 1" };
UnexpectedM unexpected1(etl::move(input1));
ErrorM input2 = { "error 2" };
UnexpectedM unexpected2(etl::move(input2));
ExpectedVM expected1(etl::move(unexpected1));
ExpectedVM expected2(etl::move(unexpected2));
expected2 = etl::move(expected1);
ErrorM output1 = etl::move(expected1.error());
ErrorM output2 = etl::move(expected2.error());
CHECK_FALSE(expected1.has_value());
CHECK_FALSE(expected2.has_value());
CHECK_EQUAL("", output1.e);
CHECK_EQUAL("error 1", output2.e);
}
};
}

View File

@ -694,6 +694,16 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_front_return)
{
DataNDC data;
data.emplace_front("24");
auto& front = data.emplace_front("42");
CHECK_EQUAL(front, data.front());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_after)
{

View File

@ -33,6 +33,7 @@ SOFTWARE.
#include "etl/container.h"
#include "etl/packet.h"
#include "etl/queue.h"
#include "etl/circular_buffer.h"
#include <iostream>
@ -196,6 +197,9 @@ namespace
stoppedCount = 0;
isLampOn = false;
speed = 0;
stateEnterHistory.clear();
stateExitHistory.clear();
}
//***********************************
@ -238,6 +242,10 @@ namespace
int stoppedCount;
bool isLampOn;
int speed;
// A circular buffer is used so that data overflows won't assert in tests which don't use this data
etl::circular_buffer<StateId::enum_type, 10UL> stateEnterHistory{};
etl::circular_buffer<StateId::enum_type, 10UL> stateExitHistory{};
};
//***********************************
@ -271,9 +279,19 @@ namespace
//***********************************
etl::fsm_state_id_t on_enter_state()
{
get_fsm_context().TurnRunningLampOff();
auto& context = get_fsm_context();
context.stateEnterHistory.push(static_cast<StateId::enum_type>(get_state_id()));
context.TurnRunningLampOff();
return No_State_Change;
}
//***********************************
void on_exit_state()
{
auto& context = get_fsm_context();
context.stateExitHistory.push(static_cast<StateId::enum_type>(get_state_id()));
}
};
//***********************************
@ -301,10 +319,19 @@ namespace
//***********************************
etl::fsm_state_id_t on_enter_state()
{
get_fsm_context().TurnRunningLampOn();
auto& context = get_fsm_context();
context.stateEnterHistory.push(static_cast<StateId::enum_type>(get_state_id()));
context.TurnRunningLampOn();
return No_State_Change;
}
//***********************************
void on_exit_state()
{
auto& context = get_fsm_context();
context.stateExitHistory.push(static_cast<StateId::enum_type>(get_state_id()));
}
};
//***********************************
@ -336,11 +363,21 @@ namespace
return No_State_Change;
}
//***********************************
etl::fsm_state_id_t on_enter_state()
{
++get_fsm_context().windUpStartCount;
auto& context = get_fsm_context();
context.stateEnterHistory.push(static_cast<StateId::enum_type>(get_state_id()));
++context.windUpStartCount;
return No_State_Change;
}
//***********************************
void on_exit_state()
{
auto& context = get_fsm_context();
context.stateExitHistory.push(static_cast<StateId::enum_type>(get_state_id()));
}
};
//***********************************
@ -371,6 +408,13 @@ namespace
++get_fsm_context().unknownCount;
return No_State_Change;
}
//***********************************
void on_exit_state()
{
auto& context = get_fsm_context();
context.stateExitHistory.push(static_cast<StateId::enum_type>(get_state_id()));
}
};
//***********************************
@ -852,5 +896,87 @@ namespace
CHECK_THROW(mc.set_states(stateList, StateId::Number_Of_States), etl::fsm_state_list_order_exception);
}
//*************************************************************************
TEST(test_hfsm_start_enters)
{
MotorControl mc;
motorControl.Initialise(stateList, std::size(stateList));
motorControl.reset();
motorControl.ClearStatistics();
CHECK(!motorControl.is_started());
// Start the HFSM (with enters)
motorControl.start(true);
CHECK(motorControl.is_started());
// Now in Idle state.
CHECK_EQUAL(StateId::Idle, int(motorControl.get_state_id()));
CHECK_EQUAL(StateId::Idle, int(motorControl.get_state().get_state_id()));
CHECK_EQUAL(false, motorControl.isLampOn);
CHECK_EQUAL(0, motorControl.setSpeedCount);
CHECK_EQUAL(0, motorControl.speed);
CHECK_EQUAL(0, motorControl.startCount);
CHECK_EQUAL(0, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.windUpCompleteCount);
CHECK_EQUAL(0, motorControl.windUpStartCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.unknownCount);
etl::array<StateId::enum_type, 1UL> expectedEnters{StateId::Idle};
CHECK_EQUAL(expectedEnters.size(), motorControl.stateEnterHistory.size());
// No enters should have been performed
CHECK(motorControl.stateExitHistory.empty());
bool entersCorrect = std::equal(motorControl.stateEnterHistory.begin(), motorControl.stateEnterHistory.end(), expectedEnters.begin());
CHECK(entersCorrect);
}
//*************************************************************************
TEST(test_hfsm_reset_exits)
{
MotorControl mc;
motorControl.Initialise(stateList, std::size(stateList));
motorControl.reset();
motorControl.ClearStatistics();
CHECK(!motorControl.is_started());
// Start the HFSM (with enters)
motorControl.start(false);
CHECK(motorControl.is_started());
// Now in Idle state.
// Send Start event.
motorControl.receive(Start());
// Send Timeout event
motorControl.receive(Timeout());
// Send SetSpeed event.
motorControl.receive(SetSpeed(100));
CHECK_EQUAL(StateId::At_Speed, int(motorControl.get_state_id()));
CHECK_EQUAL(StateId::At_Speed, int(motorControl.get_state().get_state_id()));
// Clean statistics before reset for clean results
motorControl.ClearStatistics();
// Reset HFSM (with exits)
motorControl.reset(true);
etl::array<StateId::enum_type, 2UL> expectedExits{StateId::At_Speed, StateId::Running};
CHECK_EQUAL(expectedExits.size(), motorControl.stateExitHistory.size());
// No enters should have been performed
CHECK(motorControl.stateEnterHistory.empty());
bool exitsCorrect = std::equal(motorControl.stateExitHistory.begin(), motorControl.stateExitHistory.end(), expectedExits.begin());
CHECK(exitsCorrect);
}
};
}

View File

@ -715,6 +715,18 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
DataNDC data;
std::string value1("A");
std::string value2("B");
data.emplace_back(value1);
auto& back = data.emplace_back(value2);
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr)
{

View File

@ -731,6 +731,16 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_front_return)
{
DataNDC data;
data.emplace_front("24");
auto& front = data.emplace_front("42");
CHECK_EQUAL(front, data.front());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_front_excess)
{
@ -887,6 +897,16 @@ namespace
CHECK(are_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
DataNDC data;
data.emplace_back("24");
auto& back = data.emplace_back("42");
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_back_excess)
{

View File

@ -1344,5 +1344,179 @@ namespace
CHECK(function_was_called);
CHECK(ptr.get() == ETL_NULLPTR);
}
//*************************************************************************
struct Flags
{
Flags()
: constructed(false)
, destructed(false)
{
}
void Clear()
{
constructed = false;
destructed = false;
}
bool constructed;
bool destructed;
};
static Flags flags;
TEST(test_construct_get_destroy_object_aligned)
{
struct Data
{
Data()
: a(1)
, b(2)
{
flags.constructed = true;
}
Data(int a_, int b_)
: a(a_)
, b(b_)
{
flags.constructed = true;
}
~Data()
{
flags.destructed = true;
}
int a;
int b;
};
alignas(Data) char buffer1[sizeof(Data)];
char* pbuffer1 = buffer1;
alignas(Data) char buffer1b[sizeof(Data)];
char* pbuffer1b = buffer1b;
alignas(Data) char buffer2[sizeof(Data)];
char* pbuffer2 = buffer2;
alignas(Data) char buffer2b[sizeof(Data)];
char* pbuffer2b = buffer2b;
alignas(Data) char buffer3[sizeof(Data)];
char* pbuffer3 = buffer3;
alignas(Data) char buffer3b[sizeof(Data)];
char* pbuffer3b = buffer3b;
flags.Clear();
Data& rdata1 = etl::construct_object_at<Data>(pbuffer1);
CHECK_TRUE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(1, rdata1.a);
CHECK_EQUAL(2, rdata1.b);
flags.Clear();
Data data2(3, 4);
Data& rdata2 = etl::construct_object_at(pbuffer2, data2);
CHECK_TRUE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(data2.a, rdata2.a);
CHECK_EQUAL(data2.b, rdata2.b);
flags.Clear();
Data& rdata3 = etl::construct_object_at<Data>(pbuffer3, 5, 6);
CHECK_TRUE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(5, rdata3.a);
CHECK_EQUAL(6, rdata3.b);
memcpy(buffer1b, buffer1, sizeof(Data));
memcpy(buffer2b, buffer2, sizeof(Data));
memcpy(buffer3b, buffer3, sizeof(Data));
flags.Clear();
Data& rdata1b = etl::get_object_at<Data>(pbuffer1b);
CHECK_FALSE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(1, rdata1b.a);
CHECK_EQUAL(2, rdata1b.b);
flags.Clear();
Data& rdata2b = etl::get_object_at<Data>(pbuffer2b);
CHECK_FALSE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(data2.a, rdata2b.a);
CHECK_EQUAL(data2.b, rdata2b.b);
flags.Clear();
Data& rdata3b = etl::get_object_at<Data>(pbuffer3b);
CHECK_FALSE(flags.constructed);
CHECK_FALSE(flags.destructed);
CHECK_EQUAL(5, rdata3b.a);
CHECK_EQUAL(6, rdata3b.b);
flags.Clear();
etl::destroy_object_at<Data>(pbuffer1b);
CHECK_FALSE(flags.constructed);
CHECK_TRUE(flags.destructed);
flags.Clear();
etl::destroy_object_at<Data>(pbuffer2b);
CHECK_FALSE(flags.constructed);
CHECK_TRUE(flags.destructed);
flags.Clear();
etl::destroy_object_at<Data>(pbuffer3b);
CHECK_FALSE(flags.constructed);
CHECK_TRUE(flags.destructed);
}
TEST(test_construct_get_destroy_object_misaligned)
{
struct Data
{
Data()
: a(1)
, b(2)
{
}
Data(int a_, int b_)
: a(a_)
, b(b_)
{
}
~Data()
{
}
int a;
int b;
};
alignas(Data) char buffer1[sizeof(Data)];
char* pbuffer1 = buffer1 + 1;
alignas(Data) char buffer2[sizeof(Data)];
char* pbuffer2 = buffer2 + 1;
alignas(Data) char buffer3[sizeof(Data)];
char* pbuffer3 = buffer3 + 1;
CHECK_THROW(etl::construct_object_at<Data>(pbuffer1), etl::alignment_error);
Data data2(3, 4);
CHECK_THROW(etl::construct_object_at(pbuffer2, data2), etl::alignment_error);
CHECK_THROW(etl::construct_object_at<Data>(pbuffer3, 5, 6), etl::alignment_error);
CHECK_THROW(etl::get_object_at<Data>(pbuffer1), etl::alignment_error);
CHECK_THROW(etl::destroy_object_at<Data>(pbuffer1), etl::alignment_error);
}
};
}

View File

@ -438,6 +438,27 @@ namespace
CHECK_EQUAL(1, router3.message_unknown_count);
}
//*************************************************************************
TEST(message_broker_send_messages_to_specific_subscribers)
{
Broker broker;
Router router1(1);
Router router2(2);
Router router3(3);
Subscription subscription1{ router1, { Message1::ID, Message2::ID, Message3::ID, Message4::ID } };
Subscription subscription2{ router2, { Message1::ID, Message2::ID } };
Subscription subscription3{ router2, { Message1::ID, Message3::ID } };
broker.subscribe(subscription1);
broker.subscribe(subscription2);
broker.set_successor(router3);
broker.receive(Message1());
broker.receive(1, Message1());
broker.receive(2, Message2());
}
//*************************************************************************
TEST(message_broker_send_messages_to_subscribers_after_unsubscribe)
{

View File

@ -5,7 +5,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 John Wellbelove
Copyright(c) 2022 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
@ -85,69 +85,21 @@ namespace
std::string e;
};
using Result = etl::result<Value, Error>;
using ResultV = etl::result<void, Error>;
using ResultM = etl::result<ValueM, ErrorM>;
using ResultValueError = etl::result<Value, Error>;
using ResultVoidError = etl::result<void, Error>;
using ResultValueVoid = etl::result<Value, void>;
using ResultM = etl::result<ValueM, ErrorM>;
}
// Definitions for when the STL and compiler built-ins are not available.
#if ETL_NOT_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS)
using etl::is_copy_constructible;
using etl::is_move_constructible;
//*************************
template <>
struct etl::is_copy_constructible<Value> : public etl::true_type
{
};
template <>
struct etl::is_move_constructible<Value> : public etl::true_type
{
};
template <>
struct etl::is_copy_constructible<Error> : public etl::true_type
{
};
template <>
struct etl::is_move_constructible<Error> : public etl::true_type
{
};
//*************************
template <>
struct etl::is_copy_constructible<ValueM> : public etl::false_type
{
};
template <>
struct etl::is_move_constructible<ValueM> : public etl::false_type
{
};
template <>
struct etl::is_copy_constructible<ErrorM> : public etl::false_type
{
};
template <>
struct etl::is_move_constructible<ErrorM> : public etl::false_type
{
};
#endif
namespace
{
SUITE(test_result)
{
//*************************************************************************
TEST(test_constructor_for_result_with_value)
TEST(test_construct_result_value_error_type_with_value)
{
Value input = { "value 1" };
Result result(input);
ResultValueError result(input);
Value output = result.value();
@ -157,10 +109,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_const_result_with_value)
TEST(test_construct_const_result_value_error_type_with_value)
{
Value input = { "value 1" };
const Result result(input);
const ResultValueError result(input);
const Value& output = result.value();
@ -170,7 +122,7 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_with_value)
TEST(test_construct_moveable_result_value_error_type_with_value)
{
ValueM input = { "value 1" };
ResultM result(etl::move(input));
@ -183,10 +135,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_result_with_error)
TEST(test_construct_result_value_error_type_with_error)
{
Error input = { "error 1" };
Result result(input);
ResultValueError result(input);
Error output = result.error();
@ -196,10 +148,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_const_result_with_error)
TEST(test_construct_const_result_value_error_type_with_error)
{
Error input = { "error 1" };
const Result result(input);
const ResultValueError result(input);
const Error& output = result.error();
@ -209,7 +161,7 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_with_error)
TEST(test_construct_moveable_result_value_error_type_with_error)
{
ErrorM input = { "error 1" };
ResultM result(etl::move(input));
@ -222,28 +174,28 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_result_void_value_with_value)
TEST(test_default_construct_result_void_error_type)
{
ResultV result;
ResultVoidError result;
CHECK(!result.is_value());
CHECK(result.is_error());
CHECK(result.is_value());
CHECK(!result.is_error());
}
//*************************************************************************
TEST(test_constructor_for_const_result_void_value_with_value)
TEST(test_default_construct_const_result_void_error_type)
{
const ResultV result;
const ResultVoidError result;
CHECK(!result.is_value());
CHECK(result.is_error());
CHECK(result.is_value());
CHECK(!result.is_error());
}
//*************************************************************************
TEST(test_constructor_for_result_void_value_with_error)
TEST(test_construct_result_void_error_type_with_error)
{
Error input = { "error 1" };
ResultV result(input);
ResultVoidError result(input);
Error output = result.error();
@ -253,10 +205,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_const_result_void_value_with_error)
TEST(test_construct_const_result_void_error_type_with_error)
{
Error input = { "error 1" };
const ResultV result(input);
const ResultVoidError result(input);
const Error& output = result.error();
@ -266,10 +218,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_moveable_result_void_value_with_error)
TEST(test_construct_moveable_result_void_error_type_with_error)
{
Error input = { "error 1" };
ResultV result(etl::move(input));
ResultVoidError result(etl::move(input));
Error output = etl::move(result.error());
@ -279,10 +231,10 @@ namespace
}
//*************************************************************************
TEST(test_constructor_for_moveable_const_result_void_value_with_error)
TEST(test_construct_moveable_const_result_void_error_type_with_error)
{
Error input = { "error 1" };
const ResultV result(etl::move(input));
const ResultVoidError result(etl::move(input));
Error output = etl::move(result.error());
@ -291,13 +243,83 @@ namespace
CHECK(output.e == std::string("error 1"));
}
//*************************************************************************
TEST(test_default_construct_result_value_void_type)
{
ResultValueVoid result;
CHECK(!result.is_value());
CHECK(result.is_error());
}
//*************************************************************************
TEST(test_default_construct_const_result_value_void_type)
{
const ResultValueVoid result;
CHECK(!result.is_value());
CHECK(result.is_error());
}
//*************************************************************************
TEST(test_construct_result_value_void_type_with_value)
{
Value input = { "value 1" };
ResultValueVoid result(input);
Value output = result.value();
CHECK(result.is_value());
CHECK(!result.is_error());
CHECK(output.v == input.v);
}
//*************************************************************************
TEST(test_construct_const_result_value_void_type_with_value)
{
Value input = { "value 1" };
const ResultValueVoid result(input);
const Value output = result.value();
CHECK(result.is_value());
CHECK(!result.is_error());
CHECK(output.v == input.v);
}
//*************************************************************************
TEST(test_construct_moveable_result_value_void_type_with_value)
{
Value input = { "value 1" };
ResultValueVoid result(etl::move(input));
Value output = etl::move(result.value());
CHECK(result.is_value());
CHECK(!result.is_error());
CHECK(output.v == std::string("value 1"));
}
//*************************************************************************
TEST(test_construct_moveable_const_result_value_void_type_with_value)
{
Value input = { "value 1" };
const ResultValueVoid result(etl::move(input));
Value output = etl::move(result.value());
CHECK(result.is_value());
CHECK(!result.is_error());
CHECK(output.v == std::string("value 1"));
}
//*************************************************************************
TEST(test_copy_construct_result)
{
Value input = { "value 1" };
Result result(input);
ResultValueError result(input);
Result result2(result);
ResultValueError result2(result);
Value output = result2.value();
@ -312,9 +334,9 @@ namespace
TEST(test_move_construct_result)
{
Value input = { "value 1" };
Result result(input);
ResultValueError result(input);
Result result2(etl::move(result));
ResultValueError result2(etl::move(result));
Value output = result.value();
Value output2 = result2.value();
@ -331,10 +353,10 @@ namespace
TEST(test_move_assign_result)
{
Value input = { "value 1" };
Result result(input);
ResultValueError result(input);
Value input2 = { "value 2" };
Result result2(result);
ResultValueError result2(result);
result2 = etl::move(result);

View File

@ -260,6 +260,7 @@ namespace
CHECK_EQUAL(0, router2.count_unknown_message);
}
//*************************************************************************
TEST(test_reference_counted_pool_exceptions)
{
using pool_message_parameters = etl::atomic_counted_message_pool::pool_message_parameters<Message1, Message2>;

View File

@ -970,6 +970,159 @@ namespace
}
}
//*************************************************************************
TEST(test_operator_equality)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };
int i;
View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view5{ data4 };
View view6;
View view7;
View view8(&i, &i);
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));
CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_FALSE(view1 == view5);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
CHECK_FALSE(view6 == view8);
CHECK_TRUE(view8 == view8);
}
//*************************************************************************
TEST(test_operator_equality_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };
int i;
View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
CView view5{ data4 };
View view6;
CView view7;
CView view8(&i, &i);
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));
CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_FALSE(view1 == view5);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
CHECK_FALSE(view6 == view8);
CHECK_TRUE(view8 == view8);
}
//*************************************************************************
TEST(test_operator_not_equal)
{
etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };
int i;
View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view5{ data4 };
View view6;
View view7;
View view8(&i, &i);
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));
CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_TRUE(view1 != view5);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
CHECK_TRUE(view6 != view8);
CHECK_FALSE(view8 != view8);
}
//*************************************************************************
TEST(test_operator_not_equal_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };
int i;
View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
CView view5{ data4 };
View view6;
View view7;
View view8(&i, &i);
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));
CHECK_FALSE(view1 != view1);
CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_TRUE(view1 != view5);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
CHECK_TRUE(view6 != view8);
CHECK_FALSE(view8 != view8);
}
#include "etl/private/diagnostic_pop.h"
};
}

View File

@ -960,6 +960,114 @@ namespace
}
}
//*************************************************************************
TEST(test_operator_equality)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view6;
View view7;
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
}
//*************************************************************************
TEST(test_operator_equality_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
View view6;
CView view7;
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
}
//*************************************************************************
TEST(test_operator_not_equal)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view6;
View view7;
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
}
//*************************************************************************
TEST(test_operator_not_equal_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
View view6;
View view7;
CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
}
#include "etl/private/diagnostic_pop.h"
};
}

View File

@ -1013,5 +1013,26 @@ namespace
CHECK(etl::hash<U16Text>()(u16text) == etl::hash<U16View>()(u16view));
CHECK(etl::hash<U32Text>()(u32text) == etl::hash<U32View>()(u32view));
}
//*************************************************************************
TEST(string_view_literal)
{
typedef etl::string_view View;
typedef etl::wstring_view WView;
typedef etl::u16string_view U16View;
typedef etl::u32string_view U32View;
using namespace etl::literals::string_literals;
View view = "Hello World"_sv;
WView wview = L"Hello World"_sv;
U16View u16view = u"Hello World"_sv;
U32View u32view = U"Hello World"_sv;
CHECK_TRUE((view == View{ "Hello World", etl::strlen("Hello World") }));
CHECK_TRUE((wview == WView{ L"Hello World", etl::strlen(L"Hello World") }));
CHECK_TRUE((u16view == U16View{ u"Hello World", etl::strlen(u"Hello World") }));
CHECK_TRUE((u32view == U32View{ U"Hello World", etl::strlen(U"Hello World") }));
}
};
}

View File

@ -542,7 +542,7 @@ namespace
#endif
//*************************************************************************
TEST(test_emplace_value)
TEST(test_emplace_value_by_type)
{
// Char.
char c = 'a';
@ -572,6 +572,37 @@ namespace
CHECK_EQUAL(text, etl::get<std::string>(variant_text_etl));
}
//*************************************************************************
TEST(test_emplace_value_by_index)
{
// Char.
char c = 'a';
test_variant_etl_3 variant_char_etl;
c = variant_char_etl.emplace<0>(c);
CHECK(c == 'a');
CHECK(etl::holds_alternative<char>(variant_char_etl));
CHECK_EQUAL(c, etl::get<char>(variant_char_etl));
// Int.
int i = 1;
test_variant_etl_3 variant_int_etl;
i = variant_int_etl.emplace<1>(i);
CHECK(i == 1);
CHECK(etl::holds_alternative<int>(variant_int_etl));
CHECK_EQUAL(i, etl::get<int>(variant_int_etl));
// String.
std::string text("Some Text");
test_variant_etl_3 variant_text_etl;
text = variant_text_etl.emplace<2>(text);
CHECK(text == "Some Text");
CHECK(etl::holds_alternative<std::string>(variant_text_etl));
CHECK_EQUAL(text, etl::get<std::string>(variant_text_etl));
}
//*************************************************************************
TEST(test_copy_constructor)
{

View File

@ -634,31 +634,6 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back)
{
Compare_Data compare_data;
Data data;
for (int i = 0; i < int(SIZE); ++i)
{
compare_data.emplace_back(i);
}
for (int i = 0; i < int(SIZE); ++i)
{
data.emplace_back(i);
}
CHECK_EQUAL(compare_data.size(), data.size());
bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_back_literal)
{
@ -697,6 +672,41 @@ namespace
CHECK_THROW(data.push_back(SIZE), etl::vector_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back)
{
Compare_Data compare_data;
Data data;
for (int i = 0; i < int(SIZE); ++i)
{
compare_data.emplace_back(i);
}
for (int i = 0; i < int(SIZE); ++i)
{
data.emplace_back(i);
}
CHECK_EQUAL(compare_data.size(), data.size());
bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
Data data;
data.emplace_back(24);
auto back = data.emplace_back(42);
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_pop_back)
{

View File

@ -685,6 +685,41 @@ namespace
CHECK_THROW(data.push_back(SIZE), etl::vector_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back)
{
Compare_Data compare_data;
Data data(buffer1, SIZE);
for (int i = 0; i < int(SIZE); ++i)
{
compare_data.emplace_back(i);
}
for (int i = 0; i < int(SIZE); ++i)
{
data.emplace_back(i);
}
CHECK_EQUAL(compare_data.size(), data.size());
bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
Data data(buffer1, SIZE);
data.emplace_back(24);
auto back = data.emplace_back(42);
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_pop_back)
{

View File

@ -662,29 +662,6 @@ namespace
CHECK_THROW(data.push_back(NDC("Z")), etl::vector_full);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back)
{
CompareDataNDC compare_data;
DataNDC data;
for (size_t i = 0UL; i < SIZE; ++i)
{
std::string value(" ");
value[0] = char('A' + i);
compare_data.emplace_back(value, i);
data.emplace_back(value, i);
}
CHECK_EQUAL(compare_data.size(), data.size());
bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr)
{
@ -711,6 +688,39 @@ namespace
CHECK_EQUAL(4, *data[3]);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back)
{
CompareDataNDC compare_data;
DataNDC data;
for (size_t i = 0UL; i < SIZE; ++i)
{
std::string value(" ");
value[0] = char('A' + i);
compare_data.emplace_back(value, i);
data.emplace_back(value, i);
}
CHECK_EQUAL(compare_data.size(), data.size());
bool is_equal = std::equal(data.begin(),
data.end(),
compare_data.begin());
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
DataNDC data;
data.emplace_back("A", 24);
auto back = data.emplace_back("B", 42);
CHECK_EQUAL(back, data.back());
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_insert_int)
{

View File

@ -1057,6 +1057,17 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
Data data;
int d1 = 22;
int d2 = 42;
data.emplace_back(&d1);
CHECK_EQUAL(&d2, data.emplace_back(&d2));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_pop_back)
{

View File

@ -1043,6 +1043,17 @@ namespace
CHECK(is_equal);
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_emplace_back_return)
{
Data data(buffer1, SIZE);
int d1 = 42;
int d2 = 24;
data.emplace_back(&d1);
CHECK_EQUAL(&d2, data.emplace_back(&d2));
}
//*************************************************************************
TEST_FIXTURE(SetupFixture, test_pop_back)
{

View File

@ -38,3 +38,16 @@
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_NULLPTR
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_NODISCARD [[nodiscard]]
#define ETL_NODISCARD
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_CONSTEXPR
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
// such as names of functions and macros.
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
#define ETL_NOEXCEPT

View File

@ -4747,6 +4747,34 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_m17.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Small Strings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - No STL - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Force Constexpr Algorithms|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Force Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM - No STL - Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - String Truncation Is Error|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No STL - Force No Advanced|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Force cpp03|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Intel - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Intel|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_maxim.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Force Built-ins|Win32'">true</ExcludedFromBuild>
@ -5801,6 +5829,34 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\expected.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Small Strings|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='MSVC Debug - No STL - Appveyor|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Force Constexpr Algorithms|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No Unit Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No STL - Force Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug LLVM - No STL - Built-ins|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - String Truncation Is Error|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Clang|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - No STL - Force No Advanced|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Force cpp03|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Intel - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug Intel|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - No Checks|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sanity-check\message_broker.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC - Small Strings|Win32'">true</ExcludedFromBuild>
@ -11695,6 +11751,7 @@
<ClCompile Include="..\test_crc16_en13757.cpp" />
<ClCompile Include="..\test_crc16_genibus.cpp" />
<ClCompile Include="..\test_crc16_kermit.cpp" />
<ClCompile Include="..\test_crc16_m17.cpp" />
<ClCompile Include="..\test_crc16_maxim.cpp" />
<ClCompile Include="..\test_crc16_mcrf4xx.cpp" />
<ClCompile Include="..\test_crc16_profibus.cpp" />
@ -11726,6 +11783,7 @@
<ClCompile Include="..\test_crc8_maxim.cpp" />
<ClCompile Include="..\test_crc8_rohc.cpp" />
<ClCompile Include="..\test_crc8_wcdma.cpp" />
<ClCompile Include="..\test_expected.cpp" />
<ClCompile Include="..\test_message_broker.cpp" />
<ClCompile Include="..\test_poly_span_dynamic_extent.cpp" />
<ClCompile Include="..\test_poly_span_fixed_extent.cpp" />

View File

@ -345,9 +345,6 @@
<ClInclude Include="..\..\include\etl\io_port.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\optional.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\set.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
@ -1344,6 +1341,9 @@
<ClInclude Include="..\etl_error_handler\log_errors_and_exceptions\etl_profile.h">
<Filter>Tests\Error Handler\Exceptions_And_Log_Errors</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\optional.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test_string_char.cpp">
@ -2192,9 +2192,6 @@
<ClCompile Include="..\test_random.cpp">
<Filter>Tests\Maths</Filter>
</ClCompile>
<ClCompile Include="..\test_optional.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_error_handler.cpp">
<Filter>Tests\Errors</Filter>
</ClCompile>
@ -2231,9 +2228,6 @@
<ClCompile Include="..\test_parameter_type.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\test_result.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\test_utility.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
@ -3389,6 +3383,24 @@
<ClCompile Include="..\sanity-check\to_arithmetic.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_crc16_m17.cpp">
<Filter>Tests\CRC</Filter>
</ClCompile>
<ClCompile Include="..\test_optional.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\test_result.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_expected.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\expected.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\sanity-check\crc16_m17.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\etl_error_handler\log_errors_and_exceptions\test_error_handler.cpp">
<Filter>Tests\Error Handler\Exceptions_And_Log_Errors</Filter>
</ClCompile>

View File

@ -1 +1 @@
20.35.8
20.35.12