diff --git a/.github/workflows/sanity-checks.yml b/.github/workflows/gcc-sanity-checks.yml
similarity index 78%
rename from .github/workflows/sanity-checks.yml
rename to .github/workflows/gcc-sanity-checks.yml
index 9dc3e314..60054275 100644
--- a/.github/workflows/sanity-checks.yml
+++ b/.github/workflows/gcc-sanity-checks.yml
@@ -270,4 +270,80 @@ jobs:
export CXX=g++
cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/sanity-check/c++17
gcc --version
+ make
+
+ build-gcc-cpp20-linux-STL:
+ name: GCC C++20 Linux STL
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Build
+ run: |
+ git fetch
+ export CC=gcc
+ export CXX=g++
+ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/sanity-check/c++20
+ gcc --version
+ make
+
+ build-gcc-cpp20-linux-No-STL:
+ name: GCC C++20 Linux No STL
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Build
+ run: |
+ git fetch
+ export CC=gcc
+ export CXX=g++
+ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF ./test/sanity-check/c++20
+ gcc --version
+ make
+
+ build-gcc-cpp20-linux-STL-Force-CPP03:
+ name: GCC C++20 Linux STL Force C++03
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Build
+ run: |
+ git fetch
+ export CC=gcc
+ export CXX=g++
+ cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/sanity-check/c++20
+ gcc --version
+ make
+
+ build-gcc-cpp20-linux-No-STL-Force-CPP03:
+ name: GCC C++20 Linux No STL Force C++03
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Build
+ run: |
+ git fetch
+ export CC=gcc
+ export CXX=g++
+ cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON ./test/sanity-check/c++20
+ gcc --version
make
\ No newline at end of file
diff --git a/test/sanity-check/c++20/CMakeLists.txt b/test/sanity-check/c++20/CMakeLists.txt
new file mode 100644
index 00000000..c91c46fe
--- /dev/null
+++ b/test/sanity-check/c++20/CMakeLists.txt
@@ -0,0 +1,295 @@
+cmake_minimum_required(VERSION 3.5.0)
+project(etl_20sanity_tests)
+
+add_definitions(-DETL_DEBUG)
+
+option(NO_STL "No STL" OFF)
+
+message(STATUS "Compiling for C++20")
+
+if (NO_STL)
+ message(STATUS "Compiling for No STL")
+ add_definitions(-DETL_NO_STL)
+else()
+ message(STATUS "Compiling for STL")
+endif()
+
+if (ETL_USE_TYPE_TRAITS_BUILTINS)
+ message(STATUS "Compiling for built-in type traits")
+ add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS)
+endif()
+
+if (ETL_USER_DEFINED_TYPE_TRAITS)
+ message(STATUS "Compiling for user defined type traits")
+ add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS)
+endif()
+
+if (ETL_FORCE_TEST_CPP03_IMPLEMENTATION)
+ message(STATUS "Force C++03 implementations")
+ add_definitions(-DETL_FORCE_TEST_CPP03_IMPLEMENTATION)
+endif()
+
+add_library(t20 OBJECT)
+target_compile_definitions(t20 PRIVATE __STDC_LIMIT_MACROS __STDC_CONSTANT_MACROS __STDC_FORMAT_MACROS)
+target_include_directories(t20 PRIVATE "")
+target_include_directories(t20 SYSTEM PRIVATE ../../../include)
+set_target_properties(t20 PROPERTIES
+ CXX_STANDARD 20
+ CXX_STANDARD_REQUIRED ON
+ CXX_EXTENSIONS ON
+ )
+target_sources(t20 PRIVATE etl_profile.h
+ ../absolute.h.t.cpp
+ ../algorithm.h.t.cpp
+ ../alignment.h.t.cpp
+ ../array.h.t.cpp
+ ../array_view.h.t.cpp
+ ../array_wrapper.h.t.cpp
+ ../atomic.h.t.cpp
+ ../basic_format_spec.h.t.cpp
+ ../basic_string.h.t.cpp
+ ../basic_string_stream.h.t.cpp
+ ../binary.h.t.cpp
+ ../bip_buffer_spsc_atomic.h.t.cpp
+ ../bit.h.t.cpp
+ ../bitset_legacy.h.t.cpp
+ ../bitset_new.h.t.cpp
+ ../bit_stream.h.t.cpp
+ ../byte.h.t.cpp
+ ../byte_stream.h.t.cpp
+ ../bloom_filter.h.t.cpp
+ ../bresenham_line.h.t.cpp
+ ../buffer_descriptors.h.t.cpp
+ ../callback.h.t.cpp
+ ../callback_service.h.t.cpp
+ ../callback_timer.h.t.cpp
+ ../callback_timer_atomic.h.t.cpp
+ ../callback_timer_interrupt.h.t.cpp
+ ../callback_timer_locked.h.t.cpp
+ ../char_traits.h.t.cpp
+ ../checksum.h.t.cpp
+ ../circular_buffer.h.t.cpp
+ ../circular_iterator.h.t.cpp
+ ../combinations.h.t.cpp
+ ../compare.h.t.cpp
+ ../constant.h.t.cpp
+ ../container.h.t.cpp
+ ../correlation.h.t.cpp
+ ../covariance.h.t.cpp
+ ../crc16.h.t.cpp
+ ../crc16_a.h.t.cpp
+ ../crc16_arc.h.t.cpp
+ ../crc16_aug_ccitt.h.t.cpp
+ ../crc16_buypass.h.t.cpp
+ ../crc16_ccitt.h.t.cpp
+ ../crc16_cdma2000.h.t.cpp
+ ../crc16_dds110.h.t.cpp
+ ../crc16_dectr.h.t.cpp
+ ../crc16_dectx.h.t.cpp
+ ../crc16_dnp.h.t.cpp
+ ../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
+ ../crc16_profibus.h.t.cpp
+ ../crc16_riello.h.t.cpp
+ ../crc16_t10dif.h.t.cpp
+ ../crc16_teledisk.h.t.cpp
+ ../crc16_tms37157.h.t.cpp
+ ../crc16_usb.h.t.cpp
+ ../crc16_x25.h.t.cpp
+ ../crc16_xmodem.h.t.cpp
+ ../crc32.h.t.cpp
+ ../crc32_bzip2.h.t.cpp
+ ../crc32_c.h.t.cpp
+ ../crc32_d.h.t.cpp
+ ../crc32_jamcrc.h.t.cpp
+ ../crc32_mpeg2.h.t.cpp
+ ../crc32_posix.h.t.cpp
+ ../crc32_q.h.t.cpp
+ ../crc32_xfer.h.t.cpp
+ ../crc64_ecma.h.t.cpp
+ ../crc8_ccitt.h.t.cpp
+ ../crc8_cdma2000.h.t.cpp
+ ../crc8_darc.h.t.cpp
+ ../crc8_dvbs2.h.t.cpp
+ ../crc8_ebu.h.t.cpp
+ ../crc8_icode.h.t.cpp
+ ../crc8_itu.h.t.cpp
+ ../crc8_maxim.h.t.cpp
+ ../crc8_rohc.h.t.cpp
+ ../crc8_wcdma.h.t.cpp
+ ../cyclic_value.h.t.cpp
+ ../debounce.h.t.cpp
+ ../debug_count.h.t.cpp
+ ../delegate.h.t.cpp
+ ../delegate_service.h.t.cpp
+ ../deque.h.t.cpp
+ ../endianness.h.t.cpp
+ ../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
+ ../fixed_iterator.h.t.cpp
+ ../fixed_sized_memory_block_allocator.h.t.cpp
+ ../flags.h.t.cpp
+ ../flat_map.h.t.cpp
+ ../flat_multimap.h.t.cpp
+ ../flat_multiset.h.t.cpp
+ ../flat_set.h.t.cpp
+ ../fnv_1.h.t.cpp
+ ../format_spec.h.t.cpp
+ ../forward_list.h.t.cpp
+ ../frame_check_sequence.h.t.cpp
+ ../fsm.h.t.cpp
+ ../function.h.t.cpp
+ ../functional.h.t.cpp
+ ../gamma.h.t.cpp
+ ../generic_pool.h.t.cpp
+ ../hash.h.t.cpp
+ ../ihash.h.t.cpp
+ ../histogram.h.t.cpp
+ ../imemory_block_allocator.h.t.cpp
+ ../indirect_vector.h.t.cpp
+ ../initializer_list.h.t.cpp
+ ../instance_count.h.t.cpp
+ ../integral_limits.h.t.cpp
+ ../intrusive_forward_list.h.t.cpp
+ ../intrusive_links.h.t.cpp
+ ../intrusive_list.h.t.cpp
+ ../intrusive_queue.h.t.cpp
+ ../intrusive_stack.h.t.cpp
+ ../io_port.h.t.cpp
+ ../ipool.h.t.cpp
+ ../ireference_counted_message_pool.h.t.cpp
+ ../iterator.h.t.cpp
+ ../jenkins.h.t.cpp
+ ../largest.h.t.cpp
+ ../limiter.h.t.cpp
+ ../limits.h.t.cpp
+ ../list.h.t.cpp
+ ../log.h.t.cpp
+ ../macros.h.t.cpp
+ ../map.h.t.cpp
+ ../math_constants.h.t.cpp
+ ../mean.h.t.cpp
+ ../mem_cast.h.t.cpp
+ ../memory.h.t.cpp
+ ../memory_model.h.t.cpp
+ ../message.h.t.cpp
+ ../message_broker.h.t.cpp
+ ../message_bus.h.t.cpp
+ ../message_packet.h.t.cpp
+ ../message_router.h.t.cpp
+ ../message_router_registry.h.t.cpp
+ ../message_timer.h.t.cpp
+ ../message_timer_atomic.h.t.cpp
+ ../message_timer_interrupt.h.t.cpp
+ ../message_timer_locked.h.t.cpp
+ ../message_types.h.t.cpp
+ ../multimap.h.t.cpp
+ ../multiset.h.t.cpp
+ ../multi_array.h.t.cpp
+ ../multi_range.h.t.cpp
+ ../multi_span.h.t.cpp
+ ../multi_vector.h.t.cpp
+ ../murmur3.h.t.cpp
+ ../mutex.h.t.cpp
+ ../negative.h.t.cpp
+ ../nth_type.h.t.cpp
+ ../nullptr.h.t.cpp
+ ../null_type.h.t.cpp
+ ../numeric.h.t.cpp
+ ../observer.h.t.cpp
+ ../optional.h.t.cpp
+ ../overload.h.t.cpp
+ ../packet.h.t.cpp
+ ../parameter_pack.h.t.cpp
+ ../parameter_type.h.t.cpp
+ ../pearson.h.t.cpp
+ ../permutations.h.t.cpp
+ ../placement_new.h.t.cpp
+ ../platform.h.t.cpp
+ ../poly_span.h.t.cpp
+ ../pool.h.t.cpp
+ ../power.h.t.cpp
+ ../priority_queue.h.t.cpp
+ ../pseudo_moving_average.h.t.cpp
+ ../quantize.h.t.cpp
+ ../queue.h.t.cpp
+ ../queue_lockable.h.t.cpp
+ ../queue_mpmc_mutex.h.t.cpp
+ ../queue_spsc_atomic.h.t.cpp
+ ../queue_spsc_isr.h.t.cpp
+ ../queue_spsc_locked.h.t.cpp
+ ../radix.h.t.cpp
+ ../random.h.t.cpp
+ ../ratio.h.t.cpp
+ ../reference_counted_message.h.t.cpp
+ ../reference_counted_message_pool.h.t.cpp
+ ../reference_counted_object.h.t.cpp
+ ../reference_flat_map.h.t.cpp
+ ../reference_flat_multimap.h.t.cpp
+ ../reference_flat_multiset.h.t.cpp
+ ../reference_flat_set.h.t.cpp
+ ../rescale.h.t.cpp
+ ../rms.h.t.cpp
+ ../scaled_rounding.h.t.cpp
+ ../scheduler.h.t.cpp
+ ../set.h.t.cpp
+ ../shared_message.h.t.cpp
+ ../singleton.h.t.cpp
+ ../smallest.h.t.cpp
+ ../span.h.t.cpp
+ ../sqrt.h.t.cpp
+ ../stack.h.t.cpp
+ ../standard_deviation.h.t.cpp
+ ../state_chart.h.t.cpp
+ ../static_assert.h.t.cpp
+ ../string.h.t.cpp
+ ../string_stream.h.t.cpp
+ ../string_utilities.h.t.cpp
+ ../string_view.h.t.cpp
+ ../successor.h.t.cpp
+ ../task.h.t.cpp
+ ../threshold.h.t.cpp
+ ../timer.h.t.cpp
+ ../to_arithmetic.h.t.cpp
+ ../to_string.h.t.cpp
+ ../to_u16string.h.t.cpp
+ ../to_u32string.h.t.cpp
+ ../to_wstring.h.t.cpp
+ ../type_def.h.t.cpp
+ ../type_lookup.h.t.cpp
+ ../type_select.h.t.cpp
+ ../type_traits.h.t.cpp
+ ../u16format_spec.h.t.cpp
+ ../u16string.h.t.cpp
+ ../u16string_stream.h.t.cpp
+ ../u32format_spec.h.t.cpp
+ ../u32string.h.t.cpp
+ ../u32string_stream.h.t.cpp
+ ../unaligned_type.h.t.cpp
+ ../unordered_map.h.t.cpp
+ ../unordered_multimap.h.t.cpp
+ ../unordered_multiset.h.t.cpp
+ ../unordered_set.h.t.cpp
+ ../user_type.h.t.cpp
+ ../utility.h.t.cpp
+ ../variance.h.t.cpp
+ ../variant_legacy.h.t.cpp
+ ../variant_variadic.h.t.cpp
+ ../variant_pool.h.t.cpp
+ ../vector.h.t.cpp
+ ../version.h.t.cpp
+ ../visitor.h.t.cpp
+ ../wformat_spec.h.t.cpp
+ ../wstring.h.t.cpp
+ ../wstring_stream.h.t.cpp
+ )
diff --git a/test/sanity-check/c++20/etl_profile.h b/test/sanity-check/c++20/etl_profile.h
new file mode 100644
index 00000000..ab630f66
--- /dev/null
+++ b/test/sanity-check/c++20/etl_profile.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+The MIT License(MIT)
+
+Embedded Template Library.
+https://github.com/ETLCPP/etl
+https://www.etlcpp.com
+
+Copyright(c) 2021 Bo Rydberg
+
+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_PROFILE_H__
+#define __ETL_PROFILE_H__
+
+#define ETL_TARGET_DEVICE_GENERIC
+#define ETL_TARGET_OS_NONE
+#define ETL_CPP11_SUPPORTED 1
+#define ETL_CPP14_SUPPORTED 1
+#define ETL_CPP17_SUPPORTED 1
+#define ETL_CPP20_SUPPORTED 1
+#define ETL_IN_UNIT_TEST
+#define ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK
+#define ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS
+#define ETL_CALLBACK_TIMER_ENABLE_INTERRUPTS
+#define ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK
+#define ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS
+#define ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS
+
+#if defined(ETL_FORCE_TEST_CPP03_IMPLEMENTATION)
+ #define ETL_FUNCTION_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_PRIORITY_QUEUE_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_QUEUE_ATOMIC_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_VARIANT_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_VECTOR_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_QUEUE_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_QUEUE_MPMC_MUTEX_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_QUEUE_ISR_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_QUEUE_LOCKED_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_LARGEST_TYPE_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_TYPE_SELECT_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_UNINITIALIZED_BUFFER_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_CRC_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_MEM_CAST_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_OBSERVER_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_MESSAGE_ROUTER_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_FSM_FORCE_CPP03_IMPLEMENTATION
+ #define ETL_SINGLETON_FORCE_CPP03_IMPLEMENTATION
+#endif
+
+#endif
diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj
index 8a5ddd22..14f6d4a8 100644
--- a/test/vs2022/etl.vcxproj
+++ b/test/vs2022/etl.vcxproj
@@ -3071,6 +3071,7 @@
+
@@ -13592,6 +13593,7 @@
+