mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Merge branch 'pull-request/#1002-Add-singleton_base' into development
# Conflicts: # .gitignore # include/etl/file_error_numbers.h
This commit is contained in:
commit
9bb2edfd78
@ -103,5 +103,7 @@ SOFTWARE.
|
||||
#define ETL_EXPECTED_FILE_ID "70"
|
||||
#define ETL_ALIGNMENT_FILE_ID "71"
|
||||
#define ETL_BASE64_FILE_ID "72"
|
||||
#define ETL_UNALIGNED_TYPE_FILE_ID "73"
|
||||
#define ETL_SINGLETON_BASE_FILE_ID "73"
|
||||
|
||||
#define ETL_UNALIGNED_TYPE_FILE_ID "74"
|
||||
#endif
|
||||
|
||||
172
include/etl/singleton_base.h
Normal file
172
include/etl/singleton_base.h
Normal file
@ -0,0 +1,172 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2019 John Wellbelove
|
||||
Copyright(c) 2024 BMW AG
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_SINGLETON_BASE_INCLUDED
|
||||
#define ETL_SINGLETON_BASE_INCLUDED
|
||||
|
||||
///\defgroup singleton_base singleton_base
|
||||
/// Templated version of the singleton pattern, implemented as base class
|
||||
/// for singletons.
|
||||
///\ingroup etl
|
||||
|
||||
#include "platform.h"
|
||||
#include "error_handler.h"
|
||||
#include "nullptr.h"
|
||||
#include "file_error_numbers.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//*************************************************************************
|
||||
/// Base singleton error exception.
|
||||
//*************************************************************************
|
||||
class singleton_base_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
|
||||
: exception(reason_, file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Singleton not created error exception.
|
||||
//*************************************************************************
|
||||
class singleton_base_not_created : public etl::singleton_base_exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_not_created(string_type file_name_, numeric_type line_number_)
|
||||
: singleton_base_exception(ETL_ERROR_TEXT("singleton_base:not created", ETL_SINGLETON_BASE_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Singleton instance already exists.
|
||||
//*************************************************************************
|
||||
class singleton_base_already_created : public etl::singleton_base_exception
|
||||
{
|
||||
public:
|
||||
|
||||
singleton_base_already_created(string_type file_name_, numeric_type line_number_)
|
||||
: singleton_base_exception(ETL_ERROR_TEXT("singleton_base:already created", ETL_SINGLETON_BASE_FILE_ID"A"), file_name_, line_number_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// Base class for singletons.
|
||||
/// \tparam T Any type that wants to expose the instance() interface.
|
||||
///
|
||||
/// This class is designed to work as a generic base class for any class that wants to
|
||||
/// provide a singleton interface. It'll also work for classes that do not have a
|
||||
/// default constructor.
|
||||
///
|
||||
/// Usage example:
|
||||
///
|
||||
/// class Origin
|
||||
/// : singleton<Origin>
|
||||
/// {
|
||||
/// public:
|
||||
/// Origin(int x, int y)
|
||||
/// : singleton<Origin>(*this)
|
||||
/// {}
|
||||
///
|
||||
/// int getX() const;
|
||||
/// } theOrigin(0, 0);
|
||||
///
|
||||
/// int x = Origin::instance().getX();
|
||||
///
|
||||
///
|
||||
/// Note:
|
||||
///
|
||||
/// It is important that a call to instance() will not create the instance of the class. It needs
|
||||
/// to be created by the user before calling instance(). This way, the user has better control
|
||||
/// over the instance lifetime instead of e.g. lazy initialization.
|
||||
//***********************************************************************
|
||||
template <typename T>
|
||||
class singleton_base
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************************************************
|
||||
// Returns a reference to the instance.
|
||||
//***********************************************************************
|
||||
static T& instance()
|
||||
{
|
||||
ETL_ASSERT(m_self != ETL_NULLPTR, ETL_ERROR(etl::singleton_base_not_created));
|
||||
|
||||
return *m_self;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Returns whether an instance has been attached to singleton<T> or not.
|
||||
//***********************************************************************
|
||||
static bool is_valid()
|
||||
{
|
||||
return (m_self != ETL_NULLPTR);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//***********************************************************************
|
||||
/// Constructs the instance of singleton.
|
||||
/// theInstance Reference to T, which will be returned when instance() is called.
|
||||
//***********************************************************************
|
||||
explicit singleton_base(T& theInstance)
|
||||
{
|
||||
ETL_ASSERT(m_self == ETL_NULLPTR, ETL_ERROR(etl::singleton_base_already_created));
|
||||
|
||||
m_self = &theInstance;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Removes the internal reference to the instance passed in the constructor.
|
||||
//***********************************************************************
|
||||
~singleton_base()
|
||||
{
|
||||
m_self = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static T* m_self;
|
||||
};
|
||||
|
||||
//***********************************************************************
|
||||
/// No violation of one definition rule as this is a class template
|
||||
//***********************************************************************
|
||||
template<class T>
|
||||
T* singleton_base<T>::m_self = ETL_NULLPTR;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -233,6 +233,7 @@ add_executable(etl_tests
|
||||
test_set.cpp
|
||||
test_shared_message.cpp
|
||||
test_singleton.cpp
|
||||
test_singleton_base.cpp
|
||||
test_smallest.cpp
|
||||
test_span_dynamic_extent.cpp
|
||||
test_span_fixed_extent.cpp
|
||||
|
||||
@ -260,6 +260,7 @@ target_sources(t98 PRIVATE etl_profile.h
|
||||
../set.h.t.cpp
|
||||
../shared_message.h.t.cpp
|
||||
../singleton.h.t.cpp
|
||||
../singleton_base.h.t.cpp
|
||||
../smallest.h.t.cpp
|
||||
../span.h.t.cpp
|
||||
../sqrt.h.t.cpp
|
||||
|
||||
@ -260,6 +260,7 @@ target_sources(t11 PRIVATE etl_profile.h
|
||||
../set.h.t.cpp
|
||||
../shared_message.h.t.cpp
|
||||
../singleton.h.t.cpp
|
||||
../singleton_base.h.t.cpp
|
||||
../smallest.h.t.cpp
|
||||
../span.h.t.cpp
|
||||
../sqrt.h.t.cpp
|
||||
|
||||
@ -260,6 +260,7 @@ target_sources(t14 PRIVATE etl_profile.h
|
||||
../set.h.t.cpp
|
||||
../shared_message.h.t.cpp
|
||||
../singleton.h.t.cpp
|
||||
../singleton_base.h.t.cpp
|
||||
../smallest.h.t.cpp
|
||||
../span.h.t.cpp
|
||||
../sqrt.h.t.cpp
|
||||
|
||||
@ -260,6 +260,7 @@ target_sources(t17 PRIVATE etl_profile.h
|
||||
../set.h.t.cpp
|
||||
../shared_message.h.t.cpp
|
||||
../singleton.h.t.cpp
|
||||
../singleton_base.h.t.cpp
|
||||
../smallest.h.t.cpp
|
||||
../span.h.t.cpp
|
||||
../sqrt.h.t.cpp
|
||||
|
||||
@ -260,6 +260,7 @@ target_sources(t20 PRIVATE etl_profile.h
|
||||
../set.h.t.cpp
|
||||
../shared_message.h.t.cpp
|
||||
../singleton.h.t.cpp
|
||||
../singleton_base.h.t.cpp
|
||||
../smallest.h.t.cpp
|
||||
../span.h.t.cpp
|
||||
../sqrt.h.t.cpp
|
||||
|
||||
29
test/syntax_check/singleton_base.h.t.cpp
Normal file
29
test/syntax_check/singleton_base.h.t.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2024 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/singleton_base.h>
|
||||
104
test/test_singleton_base.cpp
Normal file
104
test/test_singleton_base.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2022 John Wellbelove
|
||||
Copyright(c) 2024 BMW AG
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/singleton_base.h"
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
class Test_Singleton: public etl::singleton_base<Test_Singleton>
|
||||
{
|
||||
public:
|
||||
|
||||
Test_Singleton(int i_, std::string text_)
|
||||
: ::etl::singleton_base<Test_Singleton>(*this)
|
||||
, i(i_)
|
||||
, text(text_)
|
||||
{
|
||||
}
|
||||
|
||||
void Increment()
|
||||
{
|
||||
++i;
|
||||
text += "*";
|
||||
}
|
||||
|
||||
int i;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_singleton)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test1)
|
||||
{
|
||||
CHECK(!Test_Singleton::is_valid());
|
||||
CHECK_THROW(Test_Singleton::instance(), etl::singleton_base_not_created);
|
||||
|
||||
{
|
||||
Test_Singleton singleton(1, "Start:");
|
||||
CHECK(Test_Singleton::is_valid());
|
||||
|
||||
Test_Singleton& ts = Test_Singleton::instance();
|
||||
|
||||
CHECK_EQUAL(1, ts.i);
|
||||
CHECK_EQUAL("Start:", ts.text);
|
||||
|
||||
ts.Increment();
|
||||
|
||||
CHECK_EQUAL(2, ts.i);
|
||||
CHECK_EQUAL("Start:*", ts.text);
|
||||
|
||||
Test_Singleton* pts = &Test_Singleton::instance();
|
||||
|
||||
CHECK_EQUAL(2, ts.i);
|
||||
CHECK_EQUAL(2, pts->i);
|
||||
CHECK_EQUAL("Start:*", ts.text);
|
||||
CHECK_EQUAL("Start:*", pts->text);
|
||||
|
||||
pts->Increment();
|
||||
|
||||
CHECK_EQUAL(3, ts.i);
|
||||
CHECK_EQUAL(3, pts->i);
|
||||
CHECK_EQUAL("Start:**", ts.text);
|
||||
CHECK_EQUAL("Start:**", pts->text);
|
||||
|
||||
CHECK_THROW(Test_Singleton(2, "XYZ"), etl::singleton_base_already_created);
|
||||
}
|
||||
|
||||
CHECK(!Test_Singleton::is_valid());
|
||||
CHECK_THROW(Test_Singleton::instance(), etl::singleton_base_not_created);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3190,6 +3190,7 @@
|
||||
<ClInclude Include="..\..\include\etl\scaled_rounding.h" />
|
||||
<ClInclude Include="..\..\include\etl\shared_message.h" />
|
||||
<ClInclude Include="..\..\include\etl\singleton.h" />
|
||||
<ClInclude Include="..\..\include\etl\singleton_base.h" />
|
||||
<ClInclude Include="..\..\include\etl\span.h" />
|
||||
<ClInclude Include="..\..\include\etl\standard_deviation.h" />
|
||||
<ClInclude Include="..\..\include\etl\state_chart.h" />
|
||||
@ -7077,6 +7078,21 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\syntax_check\singleton_base.h.t.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++ 20 - No Tests|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17 - No STL|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - Optimised O2|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual messages|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\syntax_check\smallest.h.t.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
|
||||
@ -8928,6 +8944,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_singleton.cpp" />
|
||||
<ClCompile Include="..\test_singleton_base.cpp" />
|
||||
<ClCompile Include="..\test_span_dynamic_extent.cpp" />
|
||||
<ClCompile Include="..\test_span_fixed_extent.cpp" />
|
||||
<ClCompile Include="..\test_standard_deviation.cpp" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user