diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 13c8b886..781c750b 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.37.0", + "version": "20.37.1", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index 54329e4c..27e2d4d2 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.37.0 +version=20.37.1 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/delegate_observer.h b/include/etl/delegate_observer.h new file mode 100644 index 00000000..e2225cf9 --- /dev/null +++ b/include/etl/delegate_observer.h @@ -0,0 +1,262 @@ +///\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_DELEGATE_OBSERVER_INCLUDED +#define ETL_DELEGATE_OBSERVER_INCLUDED + +#include "algorithm.h" + +#include "platform.h" +#include "delegate.h" +#include "vector.h" +#include "exception.h" +#include "error_handler.h" +#include "utility.h" + +namespace etl +{ + //*************************************************************************** + ///\ingroup observer + /// The base class for delegate observer exceptions. + //*************************************************************************** + class delegate_observer_exception : public exception + { + public: + + delegate_observer_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + ///\ingroup observer + /// The exception thrown when the delegate observer list is full. + //*************************************************************************** + class delegate_observer_list_full : public delegate_observer_exception + { + public: + + delegate_observer_list_full(string_type file_name_, numeric_type line_number_) + : delegate_observer_exception(ETL_ERROR_TEXT("delegate_observable:full", ETL_DELEGATE_OBSERVER_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //********************************************************************* + /// The object that is being observed. + ///\tparam MAX_OBSERVERS The maximum number of observers that can be accommodated. + ///\ingroup observer + //********************************************************************* + template + class delegate_observable + { + public: + + typedef etl::delegate observer_type; + + private: + + //*********************************** + // Item stored in the observer list. + //*********************************** + struct observer_item + { + observer_item(observer_type observer_) + : observer(observer_) + , enabled(true) + { + } + + observer_type observer; + bool enabled; + }; + + //*********************************** + // How to compare an observer with an observer list item. + //*********************************** + struct compare_observers + { + compare_observers(observer_type& observer_) + : observer(&observer_) + { + } + + bool operator ()(const observer_item& item) const + { + return observer == item.observer; + } + + observer_type observer; + }; + + typedef etl::vector Observer_List; + + public: + + typedef size_t size_type; + typedef TNotification notification_type; + + //***************************************************************** + /// Add an observer to the list. + /// If asserts or exceptions are enabled then an etl::observable_observer_list_full + /// is emitted if the observer list is already full. + ///\param observer A reference to the observer. + //***************************************************************** + void add_observer(observer_type& observer) + { + // See if we already have it in our list. + typename Observer_List::iterator i_observer_item = find_observer(observer); + + // Not there? + if (i_observer_item == observer_list.end()) + { + // Is there enough room? + ETL_ASSERT_OR_RETURN(!observer_list.full(), ETL_ERROR(etl::observer_list_full)); + + // Add it. + observer_list.push_back(observer_item(observer)); + } + } + + //***************************************************************** + /// Remove a particular observer from the list. + ///\param observer A reference to the observer. + ///\return true if the observer was removed, false if not. + //***************************************************************** + bool remove_observer(observer_type& observer) + { + // See if we have it in our list. + typename Observer_List::iterator i_observer_item = find_observer(observer); + + // Found it? + if (i_observer_item != observer_list.end()) + { + // Erase it. + observer_list.erase(i_observer_item); + return true; + } + else + { + return false; + } + } + + //***************************************************************** + /// Enable an observer + ///\param observer A reference to the observer. + ///\param state true to enable, false to disable. Default is enable. + //***************************************************************** + void enable_observer(observer_type& observer, bool state = true) + { + // See if we have it in our list. + typename Observer_List::iterator i_observer_item = find_observer(observer); + + // Found it? + if (i_observer_item != observer_list.end()) + { + i_observer_item->enabled = state; + } + } + + //***************************************************************** + /// Disable an observer + //***************************************************************** + void disable_observer(observer_type& observer) + { + // See if we have it in our list. + typename Observer_List::iterator i_observer_item = find_observer(observer); + + // Found it? + if (i_observer_item != observer_list.end()) + { + i_observer_item->enabled = false; + } + } + + //***************************************************************** + /// Clear all observers from the list. + //***************************************************************** + void clear_observers() + { + observer_list.clear(); + } + + //***************************************************************** + /// Returns the number of observers. + //***************************************************************** + size_type number_of_observers() const + { + return observer_list.size(); + } + + //***************************************************************** + /// Notify all of the observers, sending them the notification. + ///\tparam TNotification The notification type. + ///\param n The notification. + //***************************************************************** + void notify_observers(TNotification n) + { + typename Observer_List::iterator i_observer_item = observer_list.begin(); + + while (i_observer_item != observer_list.end()) + { + if (i_observer_item->enabled) + { + i_observer_item->p_observer->notification(n); + } + + ++i_observer_item; + } + } + + protected: + + ~observable() + { + } + + private: + + //***************************************************************** + /// Find an observer in the list. + /// Returns the end of the list if not found. + //***************************************************************** + typename Observer_List::iterator find_observer(observer_type& observer_) + { + return etl::find_if(observer_list.begin(), observer_list.end(), compare_observers(observer_)); + } + + /// The list of observers. + Observer_List observer_list; + }; +} + +#endif diff --git a/include/etl/version.h b/include/etl/version.h index 65798392..2b97460d 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -40,7 +40,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 20 #define ETL_VERSION_MINOR 37 -#define ETL_VERSION_PATCH 0 +#define ETL_VERSION_PATCH 1 #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) diff --git a/library.json b/library.json index 5babfa9c..a4f35ab5 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.37.0", + "version": "20.37.1", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index de9beedf..26a95a04 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.37.0 +version=20.37.1 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index d73c7e19..6468d04e 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +20.37.1 +Fixed etl::optional arrow and dereference operators. + =============================================================================== 20.37.0 #708 Fix missing class key with friend. diff --git a/test/test_optional.cpp b/test/test_optional.cpp index fd30ac5f..c1cf0a0c 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -539,10 +539,52 @@ namespace //************************************************************************* TEST(test_optional_pod_assign_bug_714) { - etl::optional o = 42; - o = etl::nullopt; + etl::optional opt = 42; + opt = etl::nullopt; - CHECK_EQUAL(false, o.has_value()); + CHECK_EQUAL(false, opt.has_value()); + } + + //************************************************************************* + TEST(test_dereference_operator_bug_730) + { + etl::optional opt = 42; + + CHECK_EQUAL(42, *opt); + } + + //************************************************************************* + TEST(test_const_dereference_operator_bug_730) + { + const etl::optional opt = 42; + + CHECK_EQUAL(42, *opt); + } + + //************************************************************************* + TEST(test_arrow_operator_bug_730) + { + struct Object + { + int value; + }; + + etl::optional opt = Object{ 42 }; + + CHECK_EQUAL(42, opt->value); + } + + //************************************************************************* + TEST(test_const_arrow_operator_bug_730) + { + struct Object + { + int value; + }; + + const etl::optional opt = Object{ 42 }; + + CHECK_EQUAL(42, opt->value); } }; } diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 8ba2b15f..f3864279 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3398,9 +3398,6 @@ Tests\Containers - - Tests\Containers - Tests\Syntax Checks\Source @@ -3416,6 +3413,9 @@ Tests\Containers + + Tests\Misc + diff --git a/version.txt b/version.txt index 75d012d0..830f0d3c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.37.0 +20.37.1