mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge remote-tracking branch 'origin/feature/delegates' into development
# Conflicts: # include/etl/type_traits.h # include/etl/type_traits_generator.h # test/test_type_traits.cpp
This commit is contained in:
parent
d2719cb63d
commit
d2d3db1659
@ -0,0 +1,149 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "etl/delegate.h"
|
||||||
|
#include "etl/delegate_service.h"
|
||||||
|
|
||||||
|
enum VectorId
|
||||||
|
{
|
||||||
|
TIM1_CC_IRQ_HANDLER = 42,
|
||||||
|
TIM2_IRQ_HANDLER = 43,
|
||||||
|
TIM3_IRQ_HANDLER = 44,
|
||||||
|
USART1_IRQ_HANDLER = 52,
|
||||||
|
USART2_IRQ_HANDLER = 53,
|
||||||
|
VECTOR_ID_END,
|
||||||
|
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER,
|
||||||
|
VECTOR_ID_RANGE = VECTOR_ID_END - VECTOR_ID_OFFSET
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef etl::delegate_service<VECTOR_ID_RANGE, VECTOR_ID_OFFSET> InterruptVectors;
|
||||||
|
|
||||||
|
// Ensure that the callback service is initialised before use.
|
||||||
|
InterruptVectors& GetInterruptVectorsInstance()
|
||||||
|
{
|
||||||
|
static InterruptVectors interruptVectors;
|
||||||
|
|
||||||
|
return interruptVectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
|
||||||
|
|
||||||
|
// Function called from the timer1 interrupt vector.
|
||||||
|
void TIM1_CC_IRQHandler()
|
||||||
|
{
|
||||||
|
interruptVectors.call<TIM1_CC_IRQ_HANDLER>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function called from the timer2 interrupt vector.
|
||||||
|
void TIM2_IRQHandler()
|
||||||
|
{
|
||||||
|
interruptVectors.call<TIM2_IRQ_HANDLER>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function called from the timer3 interrupt vector.
|
||||||
|
void TIM3_IRQHandler()
|
||||||
|
{
|
||||||
|
interruptVectors.call<TIM3_IRQ_HANDLER>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function called from the usart1 interrupt vector.
|
||||||
|
void USART1_IRQHandler()
|
||||||
|
{
|
||||||
|
interruptVectors.call<USART1_IRQ_HANDLER>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function called from the usart2 interrupt vector.
|
||||||
|
void USART2_IRQHandler()
|
||||||
|
{
|
||||||
|
interruptVectors.call<USART2_IRQ_HANDLER>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//********************************
|
||||||
|
// Timer driver.
|
||||||
|
//********************************
|
||||||
|
class Timer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Handler for interrupts from the timer.
|
||||||
|
void InterruptHandler(const size_t id)
|
||||||
|
{
|
||||||
|
std::cout << "Timer interrupt (member) : ID " << id << "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//********************************
|
||||||
|
// Free function timer driver.
|
||||||
|
//********************************
|
||||||
|
void FreeTimerInterruptHandler(const size_t id)
|
||||||
|
{
|
||||||
|
std::cout << "Timer interrupt (free) : ID " << id << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//********************************
|
||||||
|
// UART driver.
|
||||||
|
//********************************
|
||||||
|
class Uart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructor.
|
||||||
|
Uart(int port_id, size_t interruptId)
|
||||||
|
: port_id(port_id),
|
||||||
|
callback(etl::delegate<void(size_t)>::create<Uart, &Uart::InterruptHandler>(*this))
|
||||||
|
{
|
||||||
|
GetInterruptVectorsInstance().register_delegate(interruptId, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler for interrupts from the UART.
|
||||||
|
void InterruptHandler(const size_t id)
|
||||||
|
{
|
||||||
|
std::cout << "UART" << port_id << " : ID " << id << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
etl::delegate<void(size_t)> callback;
|
||||||
|
|
||||||
|
int port_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
void UnhandledInterrupt(const size_t id)
|
||||||
|
{
|
||||||
|
std::cout << "Unhandled Interrupt : ID " << id << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declare the driver instances.
|
||||||
|
Timer timer;
|
||||||
|
Uart uart1(0, USART1_IRQ_HANDLER);
|
||||||
|
Uart uart2(1, USART2_IRQ_HANDLER);
|
||||||
|
|
||||||
|
// Declare a global callback for the timer.
|
||||||
|
// Uses the most efficient callback type for a class, as everthing is known at compile time.
|
||||||
|
etl::delegate<void(size_t)> timer_member_callback = etl::delegate<void(size_t)>::create<Timer, timer, &Timer::InterruptHandler>();
|
||||||
|
|
||||||
|
// Declare the callbacks for the free functions.
|
||||||
|
etl::delegate<void(size_t)> timer_free_callback = etl::delegate<void(size_t)>::create<FreeTimerInterruptHandler>();
|
||||||
|
etl::delegate<void(size_t)> unhandled_callback = etl::delegate<void(size_t)>::create<UnhandledInterrupt>();
|
||||||
|
|
||||||
|
//********************************
|
||||||
|
// Test it out.
|
||||||
|
//********************************
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Setup the callbacks.
|
||||||
|
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
|
||||||
|
|
||||||
|
interruptVectors.register_delegate<TIM1_CC_IRQ_HANDLER>(timer_member_callback);
|
||||||
|
interruptVectors.register_delegate<TIM2_IRQ_HANDLER>(timer_free_callback);
|
||||||
|
interruptVectors.register_unhandled_delegate(unhandled_callback);
|
||||||
|
|
||||||
|
// Simulate the interrupts.
|
||||||
|
TIM1_CC_IRQHandler();
|
||||||
|
TIM2_IRQHandler();
|
||||||
|
USART1_IRQHandler();
|
||||||
|
USART2_IRQHandler();
|
||||||
|
TIM3_IRQHandler(); // Unhandled!
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
48
examples/FunctionInterruptSimulation-Delegates/etl_profile.h
Normal file
48
examples/FunctionInterruptSimulation-Delegates/etl_profile.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2017 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ETL_PROFILE_H__
|
||||||
|
#define __ETL_PROFILE_H__
|
||||||
|
|
||||||
|
#define ETL_THROW_EXCEPTIONS
|
||||||
|
#define ETL_VERBOSE_ERRORS
|
||||||
|
#define ETL_CHECK_PUSH_POP
|
||||||
|
#define ETL_ISTRING_REPAIR_ENABLE
|
||||||
|
#define ETL_IVECTOR_REPAIR_ENABLE
|
||||||
|
#define ETL_IDEQUE_REPAIR_ENABLE
|
||||||
|
#define ETL_IN_UNIT_TEST
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include "profiles/msvc_x86.h"
|
||||||
|
#else
|
||||||
|
#include "profiles/gcc_windows_x86.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1 @@
|
|||||||
|
*.VC.opendb
|
||||||
@ -0,0 +1 @@
|
|||||||
|
*.VC.opendb
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26730.16
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FunctionInterruptSimulation-Delegates", "FunctionInterruptSimulation-Delegates.vcxproj", "{5157DB15-C255-4E47-9FB1-AF388437F90F}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x64.Build.0 = Release|x64
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{5157DB15-C255-4E47-9FB1-AF388437F90F}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {260225EB-60CB-44CC-A60C-16A23BBC10EB}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\FunctionInterruptSimulation.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\etl_profile.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>15.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{5157DB15-C255-4E47-9FB1-AF388437F90F}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>FunctionInterruptSimulation</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<AdditionalIncludeDirectories>../../../src</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
334
include/etl/delegate.h
Normal file
334
include/etl/delegate.h
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2019 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
Copyright (C) 2017 by Sergey A Kryukov: derived work
|
||||||
|
http://www.SAKryukov.org
|
||||||
|
http://www.codeproject.com/Members/SAKryukov
|
||||||
|
|
||||||
|
Based on original work by Sergey Ryazanov:
|
||||||
|
"The Impossibly Fast C++ Delegates", 18 Jul 2005
|
||||||
|
https://www.codeproject.com/articles/11015/the-impossibly-fast-c-delegates
|
||||||
|
|
||||||
|
MIT license:
|
||||||
|
http://en.wikipedia.org/wiki/MIT_License
|
||||||
|
|
||||||
|
Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibly-Fast-Cplusplus-Delegates-Fixed
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ETL_DELEGATE_INCLUDED
|
||||||
|
#define ETL_DELEGATE_INCLUDED
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#if ETL_CPP11_SUPPORTED == 0
|
||||||
|
#error NOT SUPPORTED FOR C++03 OR BELOW
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
template <typename T> class delegate;
|
||||||
|
|
||||||
|
template <typename TReturn, typename... TParams>
|
||||||
|
class delegate<TReturn(TParams...)> final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Default constructor.
|
||||||
|
//*************************************************************************
|
||||||
|
delegate() = default;
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// Copy constructor.
|
||||||
|
//*************************************************************************
|
||||||
|
delegate(const delegate& other)
|
||||||
|
{
|
||||||
|
other.invocation.clone(invocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
// Constructor from lambda or functor.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename TLambda>
|
||||||
|
delegate(const TLambda& instance)
|
||||||
|
{
|
||||||
|
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from function (Compile time).
|
||||||
|
//*************************************************************************
|
||||||
|
template <TReturn(*Method)(TParams...)>
|
||||||
|
static delegate create()
|
||||||
|
{
|
||||||
|
return delegate(nullptr, function_stub<Method>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from Lambda or Functor.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename TLambda>
|
||||||
|
static delegate create(const TLambda& instance)
|
||||||
|
{
|
||||||
|
return delegate((void*)(&instance), lambda_stub<TLambda>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from instance method (Run time).
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, TReturn(T::*Method)(TParams...)>
|
||||||
|
static delegate create(T& instance)
|
||||||
|
{
|
||||||
|
return delegate((void*)(&instance), method_stub<T, Method>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from const instance method (Run time).
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, TReturn(T::*Method)(TParams...) const>
|
||||||
|
static delegate create(const T& instance)
|
||||||
|
{
|
||||||
|
return delegate((void*)(&instance), const_method_stub<T, Method>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from instance method (Compile time).
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, T& Instance, TReturn(T::*Method)(TParams...)>
|
||||||
|
static delegate create()
|
||||||
|
{
|
||||||
|
return delegate(method_instance_stub<T, Instance, Method>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from const instance method (Compile time).
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, T const& Instance, TReturn(T::*Method)(TParams...) const>
|
||||||
|
static delegate create()
|
||||||
|
{
|
||||||
|
return delegate(const_method_instance_stub<T, Instance, Method>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Execute the delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
TReturn operator()(TParams... args) const
|
||||||
|
{
|
||||||
|
return (*invocation.stub)(invocation.object, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from function (Compile time).
|
||||||
|
//*************************************************************************
|
||||||
|
delegate& operator =(const delegate& other)
|
||||||
|
{
|
||||||
|
other.invocation.clone(invocation);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Create from Lambda or Functor.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename TLambda>
|
||||||
|
delegate& operator =(const TLambda& instance)
|
||||||
|
{
|
||||||
|
assign((void*)(&instance), lambda_stub<TLambda>);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Checks equality.
|
||||||
|
//*************************************************************************
|
||||||
|
bool operator == (const delegate& other) const
|
||||||
|
{
|
||||||
|
return invocation == other.invocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Returns <b>true</b> if the delegate is valid.
|
||||||
|
//*************************************************************************
|
||||||
|
bool operator != (const delegate& other) const
|
||||||
|
{
|
||||||
|
return invocation != other.invocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Returns <b>true</b> if the delegate is valid.
|
||||||
|
//*************************************************************************
|
||||||
|
bool is_valid() const
|
||||||
|
{
|
||||||
|
return invocation.stub != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Returns <b>true</b> if the delegate is valid.
|
||||||
|
//*************************************************************************
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
using stub_type = TReturn(*)(void* object, TParams...);
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// The internal invocation object.
|
||||||
|
//*************************************************************************
|
||||||
|
struct invocation_element
|
||||||
|
{
|
||||||
|
invocation_element() = default;
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
invocation_element(void* object_, stub_type stub_)
|
||||||
|
: object(object_)
|
||||||
|
, stub(stub_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
void clone(invocation_element& target) const
|
||||||
|
{
|
||||||
|
target.stub = stub;
|
||||||
|
target.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
bool operator ==(const invocation_element& another) const
|
||||||
|
{
|
||||||
|
return (another.stub == stub) && (another.object == object);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
bool operator !=(const invocation_element& another) const
|
||||||
|
{
|
||||||
|
return (another.stub != stub) || (another.object != object);
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************************************************
|
||||||
|
void* object = nullptr;
|
||||||
|
stub_type stub = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Constructs a delegate from an object and stub.
|
||||||
|
//*************************************************************************
|
||||||
|
delegate(void* object, stub_type stub)
|
||||||
|
{
|
||||||
|
invocation.object = object;
|
||||||
|
invocation.stub = stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Constructs a delegate from a stub.
|
||||||
|
//*************************************************************************
|
||||||
|
delegate(stub_type stub)
|
||||||
|
{
|
||||||
|
invocation.object = nullptr;
|
||||||
|
invocation.stub = stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Assign from an object and stub.
|
||||||
|
//*************************************************************************
|
||||||
|
void assign(void* object, stub_type stub)
|
||||||
|
{
|
||||||
|
invocation.object = object;
|
||||||
|
invocation.stub = stub;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a member function. Run time instance.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, TReturn(T::*Method)(TParams...)>
|
||||||
|
static TReturn method_stub(void* object, TParams... params)
|
||||||
|
{
|
||||||
|
T* p = static_cast<T*>(object);
|
||||||
|
return (p->*Method)(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a const member function. Run time instance.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, TReturn(T::*Method)(TParams...) const>
|
||||||
|
static TReturn const_method_stub(void* object, TParams... params)
|
||||||
|
{
|
||||||
|
T* const p = static_cast<T*>(object);
|
||||||
|
return (p->*Method)(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a member function. Compile time instance.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, T& Instance, TReturn(T::*Method)(TParams...)>
|
||||||
|
static TReturn method_instance_stub(void*, TParams... params)
|
||||||
|
{
|
||||||
|
return (Instance.*Method)(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a const member function. Compile time instance.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename T, const T& Instance, TReturn(T::*Method)(TParams...) const>
|
||||||
|
static TReturn const_method_instance_stub(void*, TParams... params)
|
||||||
|
{
|
||||||
|
return (Instance.*Method)(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a free function.
|
||||||
|
//*************************************************************************
|
||||||
|
template <TReturn(*Method)(TParams...)>
|
||||||
|
static TReturn function_stub(void*, TParams... params)
|
||||||
|
{
|
||||||
|
return (Method)(params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Stub call for a lambda or functor function.
|
||||||
|
//*************************************************************************
|
||||||
|
template <typename TLambda>
|
||||||
|
static TReturn lambda_stub(void* object, TParams... arg)
|
||||||
|
{
|
||||||
|
TLambda* p = static_cast<TLambda*>(object);
|
||||||
|
return (p->operator())(arg...);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// The invocation object.
|
||||||
|
//*************************************************************************
|
||||||
|
invocation_element invocation;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
157
include/etl/delegate_service.h
Normal file
157
include/etl/delegate_service.h
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2019 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ETL_DELEGATE_SERVICE_INCLUDED
|
||||||
|
#define ETL_DELEGATE_SERVICE_INCLUDED
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "nullptr.h"
|
||||||
|
#include "static_assert.h"
|
||||||
|
#include "delegate.h"
|
||||||
|
#include "array.h"
|
||||||
|
|
||||||
|
namespace etl
|
||||||
|
{
|
||||||
|
//***************************************************************************
|
||||||
|
/// An indexed delegate service.
|
||||||
|
/// \tparam RANGE The number of delegates to handle.
|
||||||
|
/// \tparam OFFSET The lowest delegate id value.
|
||||||
|
/// The delegate ids must range between OFFSET and OFFSET + RANGE - 1.
|
||||||
|
//***************************************************************************
|
||||||
|
template <const size_t RANGE, const size_t OFFSET = 0U>
|
||||||
|
class delegate_service
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Reset the delegate service.
|
||||||
|
/// Sets all delegates to the internal default.
|
||||||
|
//*************************************************************************
|
||||||
|
delegate_service()
|
||||||
|
{
|
||||||
|
etl::delegate<void(size_t)> default_delegate = etl::delegate<void(size_t)>::create<delegate_service<RANGE, OFFSET>, &delegate_service<RANGE, OFFSET>::unhandled>(*this);
|
||||||
|
|
||||||
|
lookup.fill(default_delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Registers a delegate for the specified id.
|
||||||
|
/// Compile time assert if the id is out of range.
|
||||||
|
/// \tparam ID The id of the delegate.
|
||||||
|
/// \param delegate Reference to the delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
template <const size_t ID>
|
||||||
|
void register_delegate(etl::delegate<void(size_t)> callback)
|
||||||
|
{
|
||||||
|
ETL_STATIC_ASSERT(ID < (OFFSET + RANGE), "Callback Id out of range");
|
||||||
|
ETL_STATIC_ASSERT(ID >= OFFSET, "Callback Id out of range");
|
||||||
|
|
||||||
|
lookup[ID - OFFSET] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Registers a delegate for the specified id.
|
||||||
|
/// No action if the id is out of range.
|
||||||
|
/// \param id Id of the delegate.
|
||||||
|
/// \param delegate Reference to the delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
void register_delegate(const size_t id, etl::delegate<void(size_t)> callback)
|
||||||
|
{
|
||||||
|
if ((id >= OFFSET) && (id < (OFFSET + RANGE)))
|
||||||
|
{
|
||||||
|
lookup[id - OFFSET] = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Registers an alternative delegate for unhandled ids.
|
||||||
|
/// \param delegate A reference to the user supplied 'unhandled' delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
void register_unhandled_delegate(etl::delegate<void(size_t)> callback)
|
||||||
|
{
|
||||||
|
unhandled_delegate = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Executes the delegate function for the index.
|
||||||
|
/// Compile time assert if the id is out of range.
|
||||||
|
/// \tparam ID The id of the delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
template <const size_t ID>
|
||||||
|
void call()
|
||||||
|
{
|
||||||
|
ETL_STATIC_ASSERT(ID < (OFFSET + RANGE), "Callback Id out of range");
|
||||||
|
ETL_STATIC_ASSERT(ID >= OFFSET, "Callback Id out of range");
|
||||||
|
|
||||||
|
lookup[ID - OFFSET](ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// Executes the delegate function for the index.
|
||||||
|
/// \param id Id of the delegate.
|
||||||
|
//*************************************************************************
|
||||||
|
void call(const size_t id)
|
||||||
|
{
|
||||||
|
if ((id >= OFFSET) && (id < (OFFSET + RANGE)))
|
||||||
|
{
|
||||||
|
lookup[id - OFFSET](id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (unhandled_delegate.is_valid())
|
||||||
|
{
|
||||||
|
unhandled_delegate(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
/// The default callback function.
|
||||||
|
/// Calls the user defined 'unhandled' callback if it exists.
|
||||||
|
//*************************************************************************
|
||||||
|
void unhandled(size_t id)
|
||||||
|
{
|
||||||
|
if (unhandled_delegate.is_valid())
|
||||||
|
{
|
||||||
|
unhandled_delegate(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The default delegate for unhandled ids.
|
||||||
|
etl::delegate<void(size_t)> unhandled_delegate;
|
||||||
|
|
||||||
|
/// Lookup table of delegates.
|
||||||
|
etl::array<etl::delegate<void(size_t)>, RANGE> lookup;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
143
include/etl/multicast_delegate.h
Normal file
143
include/etl/multicast_delegate.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
///\file
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2019 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
Copyright (C) 2017 by Sergey A Kryukov: derived work
|
||||||
|
http://www.SAKryukov.org
|
||||||
|
http://www.codeproject.com/Members/SAKryukov
|
||||||
|
|
||||||
|
Based on original work by Sergey Ryazanov:
|
||||||
|
"The Impossibly Fast C++ Delegates", 18 Jul 2005
|
||||||
|
https://www.codeproject.com/articles/11015/the-impossibly-fast-c-delegates
|
||||||
|
|
||||||
|
MIT license:
|
||||||
|
http://en.wikipedia.org/wiki/MIT_License
|
||||||
|
|
||||||
|
Original publication: https://www.codeproject.com/Articles/1170503/The-Impossibly-Fast-Cplusplus-Delegates-Fixed
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
//#pragma once
|
||||||
|
//#include "delegate.h"
|
||||||
|
//#include <list>
|
||||||
|
//#include <functional>
|
||||||
|
//
|
||||||
|
//namespace SA {
|
||||||
|
//
|
||||||
|
// template<typename RET, typename ...PARAMS>
|
||||||
|
// class multicast_delegate<RET(PARAMS...)> final : private delegate_base<RET(PARAMS...)> {
|
||||||
|
// public:
|
||||||
|
//
|
||||||
|
// multicast_delegate() = default;
|
||||||
|
// ~multicast_delegate() {
|
||||||
|
// for (auto& element : invocationList) delete element;
|
||||||
|
// invocationList.clear();
|
||||||
|
// } //~multicast_delegate
|
||||||
|
//
|
||||||
|
// bool isNull() const { return invocationList.size() < 1; }
|
||||||
|
// bool operator ==(void* ptr) const {
|
||||||
|
// return (ptr == nullptr) && this->isNull();
|
||||||
|
// } //operator ==
|
||||||
|
// bool operator !=(void* ptr) const {
|
||||||
|
// return (ptr != nullptr) || (!this->isNull());
|
||||||
|
// } //operator !=
|
||||||
|
//
|
||||||
|
// size_t size() const { return invocationList.size(); }
|
||||||
|
//
|
||||||
|
// multicast_delegate& operator =(const multicast_delegate&) = delete;
|
||||||
|
// multicast_delegate(const multicast_delegate&) = delete;
|
||||||
|
//
|
||||||
|
// bool operator ==(const multicast_delegate& another) const {
|
||||||
|
// if (invocationList.size() != another.invocationList.size()) return false;
|
||||||
|
// auto anotherIt = another.invocationList.begin();
|
||||||
|
// for (auto it = invocationList.begin(); it != invocationList.end(); ++it)
|
||||||
|
// if (**it != **anotherIt) return false;
|
||||||
|
// return true;
|
||||||
|
// } //==
|
||||||
|
// bool operator !=(const multicast_delegate& another) const { return !(*this == another); }
|
||||||
|
//
|
||||||
|
// bool operator ==(const delegate<RET(PARAMS...)>& another) const {
|
||||||
|
// if (isNull() && another.isNull()) return true;
|
||||||
|
// if (another.isNull() || (size() != 1)) return false;
|
||||||
|
// return (another.invocation == **invocationList.begin());
|
||||||
|
// } //==
|
||||||
|
// bool operator !=(const delegate<RET(PARAMS...)>& another) const { return !(*this == another); }
|
||||||
|
//
|
||||||
|
// multicast_delegate& operator +=(const multicast_delegate& another) {
|
||||||
|
// for (auto& item : another.invocationList) // clone, not copy; flattens hierarchy:
|
||||||
|
// this->invocationList.push_back(new typename delegate_base<RET(PARAMS...)>::InvocationElement(item->object, item->stub));
|
||||||
|
// return *this;
|
||||||
|
// } //operator +=
|
||||||
|
//
|
||||||
|
// template <typename LAMBDA> // template instantiation is not neededm, will be deduced/inferred:
|
||||||
|
// multicast_delegate& operator +=(const LAMBDA & lambda) {
|
||||||
|
// delegate<RET(PARAMS...)> d = delegate<RET(PARAMS...)>::template create<LAMBDA>(lambda);
|
||||||
|
// return *this += d;
|
||||||
|
// } //operator +=
|
||||||
|
//
|
||||||
|
// multicast_delegate& operator +=(const delegate<RET(PARAMS...)>& another) {
|
||||||
|
// if (another.isNull()) return *this;
|
||||||
|
// this->invocationList.push_back(new typename delegate_base<RET(PARAMS...)>::InvocationElement(another.invocation.object, another.invocation.stub));
|
||||||
|
// return *this;
|
||||||
|
// } //operator +=
|
||||||
|
//
|
||||||
|
// // will work even if RET is void, return values are ignored:
|
||||||
|
// // (for handling return values, see operator(..., handler))
|
||||||
|
// void operator()(PARAMS... arg) const {
|
||||||
|
// for (auto& item : invocationList)
|
||||||
|
// (*(item->stub))(item->object, arg...);
|
||||||
|
// } //operator()
|
||||||
|
//
|
||||||
|
// template<typename HANDLER>
|
||||||
|
// void operator()(PARAMS... arg, HANDLER handler) const {
|
||||||
|
// size_t index = 0;
|
||||||
|
// for (auto& item : invocationList) {
|
||||||
|
// RET value = (*(item->stub))(item->object, arg...);
|
||||||
|
// handler(index, &value);
|
||||||
|
// ++index;
|
||||||
|
// } //loop
|
||||||
|
// } //operator()
|
||||||
|
//
|
||||||
|
// void operator()(PARAMS... arg, delegate<void(size_t, RET*)> handler) const {
|
||||||
|
// operator()<decltype(handler)>(arg..., handler);
|
||||||
|
// } //operator()
|
||||||
|
// void operator()(PARAMS... arg, std::function<void(size_t, RET*)> handler) const {
|
||||||
|
// operator()<decltype(handler)>(arg..., handler);
|
||||||
|
// } //operator()
|
||||||
|
//
|
||||||
|
// private:
|
||||||
|
//
|
||||||
|
// std::list<typename delegate_base<RET(PARAMS...)>::InvocationElement *> invocationList;
|
||||||
|
//
|
||||||
|
// }; //class multicast_delegate
|
||||||
|
//
|
||||||
|
//} /* namespace SA */
|
||||||
|
//
|
||||||
@ -492,14 +492,14 @@ namespace etl
|
|||||||
///\ingroup types
|
///\ingroup types
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
|
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
|
||||||
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
|
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
|
||||||
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void,
|
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void,
|
||||||
typename T17 = void>
|
typename T17 = void>
|
||||||
struct is_one_of
|
struct is_one_of
|
||||||
{
|
{
|
||||||
static const bool value =
|
static const bool value =
|
||||||
etl::is_same<T, T1>::value ||
|
etl::is_same<T, T1>::value ||
|
||||||
etl::is_same<T, T2>::value ||
|
etl::is_same<T, T2>::value ||
|
||||||
etl::is_same<T, T3>::value ||
|
etl::is_same<T, T3>::value ||
|
||||||
@ -600,13 +600,19 @@ namespace etl
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct size_of
|
struct size_of
|
||||||
{
|
{
|
||||||
static const size_t size = sizeof(T);
|
enum
|
||||||
|
{
|
||||||
|
size = sizeof(T)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct size_of<void>
|
struct size_of<void>
|
||||||
{
|
{
|
||||||
static const size_t size = 1;
|
enum
|
||||||
|
{
|
||||||
|
size = 1
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -605,13 +605,19 @@ namespace etl
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct size_of
|
struct size_of
|
||||||
{
|
{
|
||||||
static const size_t size = sizeof(T);
|
enum
|
||||||
|
{
|
||||||
|
size = sizeof(T)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct size_of<void>
|
struct size_of<void>
|
||||||
{
|
{
|
||||||
static const size_t size = 1;
|
enum
|
||||||
|
{
|
||||||
|
size = 1
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -181,6 +181,8 @@
|
|||||||
<Unit filename="../../include/etl/cyclic_value.h" />
|
<Unit filename="../../include/etl/cyclic_value.h" />
|
||||||
<Unit filename="../../include/etl/debounce.h" />
|
<Unit filename="../../include/etl/debounce.h" />
|
||||||
<Unit filename="../../include/etl/debug_count.h" />
|
<Unit filename="../../include/etl/debug_count.h" />
|
||||||
|
<Unit filename="../../include/etl/delegate.h" />
|
||||||
|
<Unit filename="../../include/etl/delegate_service.h" />
|
||||||
<Unit filename="../../include/etl/deque.h" />
|
<Unit filename="../../include/etl/deque.h" />
|
||||||
<Unit filename="../../include/etl/doxygen.h" />
|
<Unit filename="../../include/etl/doxygen.h" />
|
||||||
<Unit filename="../../include/etl/endianness.h" />
|
<Unit filename="../../include/etl/endianness.h" />
|
||||||
@ -248,6 +250,9 @@
|
|||||||
<Unit filename="../../include/etl/pool.h" />
|
<Unit filename="../../include/etl/pool.h" />
|
||||||
<Unit filename="../../include/etl/power.h" />
|
<Unit filename="../../include/etl/power.h" />
|
||||||
<Unit filename="../../include/etl/priority_queue.h" />
|
<Unit filename="../../include/etl/priority_queue.h" />
|
||||||
|
<Unit filename="../../include/etl/private/delegate_base.h" />
|
||||||
|
<Unit filename="../../include/etl/private/delegate_base_cpp03.h" />
|
||||||
|
<Unit filename="../../include/etl/private/delegate_cpp03.h" />
|
||||||
<Unit filename="../../include/etl/private/ivectorpointer.h" />
|
<Unit filename="../../include/etl/private/ivectorpointer.h" />
|
||||||
<Unit filename="../../include/etl/private/pvoidvector.h" />
|
<Unit filename="../../include/etl/private/pvoidvector.h" />
|
||||||
<Unit filename="../../include/etl/private/to_string_helper.h" />
|
<Unit filename="../../include/etl/private/to_string_helper.h" />
|
||||||
@ -362,6 +367,8 @@
|
|||||||
<Unit filename="../test_crc.cpp" />
|
<Unit filename="../test_crc.cpp" />
|
||||||
<Unit filename="../test_cyclic_value.cpp" />
|
<Unit filename="../test_cyclic_value.cpp" />
|
||||||
<Unit filename="../test_debounce.cpp" />
|
<Unit filename="../test_debounce.cpp" />
|
||||||
|
<Unit filename="../test_delegate.cpp" />
|
||||||
|
<Unit filename="../test_delegate_service.cpp" />
|
||||||
<Unit filename="../test_deque.cpp" />
|
<Unit filename="../test_deque.cpp" />
|
||||||
<Unit filename="../test_endian.cpp" />
|
<Unit filename="../test_endian.cpp" />
|
||||||
<Unit filename="../test_enum_type.cpp" />
|
<Unit filename="../test_enum_type.cpp" />
|
||||||
|
|||||||
@ -101,22 +101,22 @@ namespace
|
|||||||
|
|
||||||
// Callback for 'unhandled'.
|
// Callback for 'unhandled'.
|
||||||
etl::function_fp<size_t, unhandled> unhandled_callback;
|
etl::function_fp<size_t, unhandled> unhandled_callback;
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Initialises the test results.
|
// Initialises the test results.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
struct SetupFixture
|
struct SetupFixture
|
||||||
{
|
|
||||||
SetupFixture()
|
|
||||||
{
|
{
|
||||||
called_id = UINT_MAX;
|
SetupFixture()
|
||||||
global_called = false;
|
{
|
||||||
member1_called = false;
|
called_id = UINT_MAX;
|
||||||
member2_called = false;
|
global_called = false;
|
||||||
unhandled_called = false;
|
member1_called = false;
|
||||||
}
|
member2_called = false;
|
||||||
};
|
unhandled_called = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|||||||
506
test/test_delegate.cpp
Normal file
506
test/test_delegate.cpp
Normal file
@ -0,0 +1,506 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
http://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2014 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "UnitTest++.h"
|
||||||
|
|
||||||
|
#include "etl/delegate.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
//*****************************************************************************
|
||||||
|
const int VALUE1 = 1;
|
||||||
|
const int VALUE2 = 2;
|
||||||
|
bool function_called = false;
|
||||||
|
bool parameter_correct = false;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Test data structure.
|
||||||
|
//*****************************************************************************
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The free function taking no parameters.
|
||||||
|
//*****************************************************************************
|
||||||
|
void free_void()
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The free function taking an int parameter.
|
||||||
|
//*****************************************************************************
|
||||||
|
void free_int(int i, int j)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (i == VALUE1) && (j == VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The free function taking a Data reference parameter.
|
||||||
|
//*****************************************************************************
|
||||||
|
void free_reference(const Data& data, int j)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (data.d == VALUE1) && (j = VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The test class with member functions.
|
||||||
|
//*****************************************************************************
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// void
|
||||||
|
void member_void()
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void member_void_const() const
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// int
|
||||||
|
void member_int(int i, int j)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (i == VALUE1) && (j == VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void member_int_const(int i, int j) const
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (i == VALUE1) && (j == VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// reference
|
||||||
|
void member_reference(const Data& data, int j)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (data.d == VALUE1) && (j = VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void member_reference_const(const Data& data, int j) const
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (data.d == VALUE1) && (j = VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// static
|
||||||
|
static void member_static(const Data& data, int j)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (data.d == VALUE1) && (j = VALUE2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
// operator()
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Test test_static;
|
||||||
|
const Test const_test_static;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Initialises the test results.
|
||||||
|
//*****************************************************************************
|
||||||
|
struct SetupFixture
|
||||||
|
{
|
||||||
|
SetupFixture()
|
||||||
|
{
|
||||||
|
function_called = false;
|
||||||
|
parameter_correct = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
SUITE(test_delegate)
|
||||||
|
{
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_is_valid_false)
|
||||||
|
{
|
||||||
|
etl::delegate<void(void)> d;
|
||||||
|
|
||||||
|
CHECK(!d.is_valid());
|
||||||
|
CHECK(!d);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_is_valid_true)
|
||||||
|
{
|
||||||
|
etl::delegate<void(void)> d([] {});
|
||||||
|
|
||||||
|
CHECK(d.is_valid());
|
||||||
|
CHECK(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_free_void)
|
||||||
|
{
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create<free_void>();
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_free_int)
|
||||||
|
{
|
||||||
|
etl::delegate<void(int, int)> d = etl::delegate<void(int, int)>::create<free_int>();
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_free_reference)
|
||||||
|
{
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<free_reference>();
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_lambda_int)
|
||||||
|
{
|
||||||
|
etl::delegate<void(int, int)> d([](int i, int j) { function_called = true; parameter_correct = (i == VALUE1) && (j == VALUE2); });
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_lambda_int_create)
|
||||||
|
{
|
||||||
|
auto lambda = [](int i, int j) { function_called = true; parameter_correct = (i == VALUE1) && (j == VALUE2); };
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d(lambda);
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_operator_void)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d(test);
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_operator_void_create)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create(test);
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_operator_void_const)
|
||||||
|
{
|
||||||
|
const Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d(test);
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_assignment_member_operator_void)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d;
|
||||||
|
|
||||||
|
d = test;
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_void)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create<Test, &Test::member_void>(test);
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_void_const)
|
||||||
|
{
|
||||||
|
const Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create<Test, &Test::member_void_const>(test);
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_int)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d = etl::delegate<void(int, int)>::create<Test, &Test::member_int>(test);
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_int_const)
|
||||||
|
{
|
||||||
|
const Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d = etl::delegate<void(int, int)>::create<Test, &Test::member_int_const>(test);
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_reference)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<Test, &Test::member_reference>(test);
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_reference_const)
|
||||||
|
{
|
||||||
|
const Test test;
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<Test, &Test::member_reference_const>(test);
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_static)
|
||||||
|
{
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<Test::member_static>();
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_void_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create<Test, test_static, &Test::member_void>();
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_void_const_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(void)> d = etl::delegate<void(void)>::create<Test, const_test_static, &Test::member_void_const>();
|
||||||
|
|
||||||
|
d();
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_int_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(int, int)> d = etl::delegate<void(int, int)>::create<Test, test_static, &Test::member_int>();
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_int_const_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(int, int)> d = etl::delegate<void(int, int)>::create<Test, const_test_static, &Test::member_int_const>();
|
||||||
|
|
||||||
|
d(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_reference_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<Test, test_static, &Test::member_reference>();
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_member_reference_const_compile_time)
|
||||||
|
{
|
||||||
|
etl::delegate<void(const Data&, int)> d = etl::delegate<void(const Data&, int)>::create<Test, const_test_static, &Test::member_reference_const>();
|
||||||
|
|
||||||
|
Data data;
|
||||||
|
data.d = VALUE1;
|
||||||
|
|
||||||
|
d(data, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_copy_construct)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d1 = etl::delegate<void(int, int)>::create<Test, &Test::member_int>(test);
|
||||||
|
etl::delegate<void(int, int)> d2(d1);
|
||||||
|
|
||||||
|
d2(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_assignment)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d1 = etl::delegate<void(int, int)>::create<Test, &Test::member_int>(test);
|
||||||
|
etl::delegate<void(int, int)> d2;
|
||||||
|
|
||||||
|
d2 = d1;
|
||||||
|
|
||||||
|
d2(VALUE1, VALUE2);
|
||||||
|
|
||||||
|
CHECK(function_called);
|
||||||
|
CHECK(parameter_correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_equal)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d1 = etl::delegate<void(int, int)>::create<Test, &Test::member_int>(test);
|
||||||
|
etl::delegate<void(int, int)> d2 = d1;
|
||||||
|
|
||||||
|
CHECK(d1 == d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_not_equal)
|
||||||
|
{
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
etl::delegate<void(int, int)> d1 = etl::delegate<void(int, int)>::create<Test, &Test::member_int>(test);
|
||||||
|
etl::delegate<void(int, int)> d2 = etl::delegate<void(int, int)>::create<Test, &Test::member_int_const>(test);;
|
||||||
|
|
||||||
|
CHECK(d1 != d2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
333
test/test_delegate_service.cpp
Normal file
333
test/test_delegate_service.cpp
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
The MIT License(MIT)
|
||||||
|
|
||||||
|
Embedded Template Library.
|
||||||
|
https://github.com/ETLCPP/etl
|
||||||
|
https://www.etlcpp.com
|
||||||
|
|
||||||
|
Copyright(c) 2019 jwellbelove
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files(the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions :
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "UnitTest++.h"
|
||||||
|
|
||||||
|
#include "etl/delegate.h"
|
||||||
|
#include "etl/delegate_service.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const size_t SIZE = 3U;
|
||||||
|
const size_t OFFSET = 5U;
|
||||||
|
|
||||||
|
using Service = etl::delegate_service<SIZE, OFFSET>;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
bool global_called = false;
|
||||||
|
bool member1_called = false;
|
||||||
|
bool member2_called = false;
|
||||||
|
bool unhandled_called = false;
|
||||||
|
size_t called_id = UINT_MAX;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The global function taking no parameters.
|
||||||
|
//*****************************************************************************
|
||||||
|
void global(size_t id)
|
||||||
|
{
|
||||||
|
global_called = true;
|
||||||
|
called_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The external unhandled callback.
|
||||||
|
//*****************************************************************************
|
||||||
|
void unhandled(size_t id)
|
||||||
|
{
|
||||||
|
unhandled_called = true;
|
||||||
|
called_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The test class with member functions.
|
||||||
|
//*****************************************************************************
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Test()
|
||||||
|
: callback(etl::delegate<void(size_t)>::create<Test, &Test::member1>(*this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void member1(size_t id)
|
||||||
|
{
|
||||||
|
member1_called = true;
|
||||||
|
called_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void member2(size_t id)
|
||||||
|
{
|
||||||
|
member2_called = true;
|
||||||
|
called_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback for 'member1'.
|
||||||
|
etl::delegate<void(size_t)> callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
Test test;
|
||||||
|
|
||||||
|
// Callback for 'member2'.
|
||||||
|
etl::delegate<void(size_t)> member_callback = etl::delegate<void(size_t)>::create<Test, test, &Test::member2>();
|
||||||
|
|
||||||
|
// Callback for 'global'.
|
||||||
|
etl::delegate<void(size_t)> global_callback = etl::delegate<void(size_t)>::create<global>();
|
||||||
|
|
||||||
|
// Callback for 'unhandled'.
|
||||||
|
etl::delegate<void(size_t)> unhandled_callback = etl::delegate<void(size_t)>::create<unhandled>();
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Initialises the test results.
|
||||||
|
//*****************************************************************************
|
||||||
|
struct SetupFixture
|
||||||
|
{
|
||||||
|
SetupFixture()
|
||||||
|
{
|
||||||
|
called_id = UINT_MAX;
|
||||||
|
global_called = false;
|
||||||
|
member1_called = false;
|
||||||
|
member2_called = false;
|
||||||
|
unhandled_called = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GLOBAL = OFFSET,
|
||||||
|
MEMBER1,
|
||||||
|
MEMBER2,
|
||||||
|
OUT_OF_RANGE
|
||||||
|
};
|
||||||
|
|
||||||
|
SUITE(test_delegate_service)
|
||||||
|
{
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_global_compile_time)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER1>(test.callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.call<GLOBAL>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(GLOBAL, called_id);
|
||||||
|
CHECK(global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_global_run_time)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate(GLOBAL, global_callback);
|
||||||
|
service.register_delegate(MEMBER1, test.callback);
|
||||||
|
service.register_delegate(MEMBER2, member_callback);
|
||||||
|
|
||||||
|
service.call(GLOBAL);
|
||||||
|
|
||||||
|
CHECK_EQUAL(GLOBAL, called_id);
|
||||||
|
CHECK(global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_member1_compile_time)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER1>(test.callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.call<MEMBER1>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(MEMBER1, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_member1_run_time)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate(GLOBAL, global_callback);
|
||||||
|
service.register_delegate(MEMBER1, test.callback);
|
||||||
|
service.register_delegate(MEMBER2, member_callback);
|
||||||
|
|
||||||
|
service.call(MEMBER1);
|
||||||
|
|
||||||
|
CHECK_EQUAL(MEMBER1, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_member2_compile_time)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER1>(test.callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.call<MEMBER2>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(MEMBER2, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_unhandled_out_of_range_run_time_default)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER1>(test.callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.call(OUT_OF_RANGE);
|
||||||
|
|
||||||
|
CHECK_EQUAL(UINT_MAX, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_unhandled_out_of_range_run_time_user_supplied)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER1>(test.callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.register_unhandled_delegate(unhandled_callback);
|
||||||
|
|
||||||
|
service.call(OUT_OF_RANGE);
|
||||||
|
|
||||||
|
CHECK_EQUAL(OUT_OF_RANGE, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_unhandled_not_registered_compile_time_default)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.call<MEMBER1>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(UINT_MAX, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_unhandled_not_registered_run_time_default)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate(GLOBAL, global_callback);
|
||||||
|
service.register_delegate(MEMBER2, member_callback);
|
||||||
|
|
||||||
|
service.call(MEMBER1);
|
||||||
|
|
||||||
|
CHECK_EQUAL(UINT_MAX, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(!unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_not_registered_compile_time_user_supplied)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate<GLOBAL>(global_callback);
|
||||||
|
service.register_delegate<MEMBER2>(member_callback);
|
||||||
|
|
||||||
|
service.register_unhandled_delegate(unhandled_callback);
|
||||||
|
|
||||||
|
service.call<MEMBER1>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(MEMBER1, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(unhandled_called);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_delegate_unhandled_run_time_user_supplied)
|
||||||
|
{
|
||||||
|
Service service;
|
||||||
|
|
||||||
|
service.register_delegate(GLOBAL, global_callback);
|
||||||
|
service.register_delegate(MEMBER2, member_callback);
|
||||||
|
|
||||||
|
service.register_unhandled_delegate(unhandled_callback);
|
||||||
|
|
||||||
|
service.call(MEMBER1);
|
||||||
|
|
||||||
|
CHECK_EQUAL(MEMBER1, called_id);
|
||||||
|
CHECK(!global_called);
|
||||||
|
CHECK(!member1_called);
|
||||||
|
CHECK(!member2_called);
|
||||||
|
CHECK(unhandled_called);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -30,123 +30,126 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "etl/function.h"
|
#include "etl/function.h"
|
||||||
|
|
||||||
//*****************************************************************************
|
namespace
|
||||||
const int VALUE = 1;
|
|
||||||
bool function_called = false;
|
|
||||||
bool parameter_correct = false;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// Test data structure.
|
|
||||||
//*****************************************************************************
|
|
||||||
struct Data
|
|
||||||
{
|
{
|
||||||
int d;
|
//*****************************************************************************
|
||||||
};
|
const int VALUE = 1;
|
||||||
|
bool function_called = false;
|
||||||
|
bool parameter_correct = false;
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the function taking no parameters.
|
// Test data structure.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(etl::ifunction<void>& function)
|
struct Data
|
||||||
{
|
{
|
||||||
function();
|
int d;
|
||||||
}
|
};
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the const function taking no parameters.
|
// Call the function taking no parameters.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(const etl::ifunction<void>& function)
|
void call(etl::ifunction<void>& function)
|
||||||
{
|
{
|
||||||
function();
|
function();
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the function taking an int parameter.
|
// Call the const function taking no parameters.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(etl::ifunction<int>& function)
|
void call(const etl::ifunction<void>& function)
|
||||||
{
|
{
|
||||||
function(VALUE);
|
function();
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the const function taking an int parameter.
|
// Call the function taking an int parameter.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(const etl::ifunction<int>& function)
|
void call(etl::ifunction<int>& function)
|
||||||
{
|
{
|
||||||
function(VALUE);
|
function(VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the function taking a Data parameter.
|
// Call the const function taking an int parameter.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(etl::ifunction<const Data&>& function)
|
void call(const etl::ifunction<int>& function)
|
||||||
{
|
{
|
||||||
Data data;
|
function(VALUE);
|
||||||
data.d = VALUE;
|
}
|
||||||
function(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Call the const function taking a Data parameter.
|
// Call the function taking a Data parameter.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void call(const etl::ifunction<const Data&>& function)
|
void call(etl::ifunction<const Data&>& function)
|
||||||
{
|
{
|
||||||
Data data;
|
Data data;
|
||||||
data.d = VALUE;
|
data.d = VALUE;
|
||||||
function(data);
|
function(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// The free function taking no parameters.
|
// Call the const function taking a Data parameter.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void free_void()
|
void call(const etl::ifunction<const Data&>& function)
|
||||||
{
|
{
|
||||||
function_called = true;
|
Data data;
|
||||||
}
|
data.d = VALUE;
|
||||||
|
function(data);
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// The free function taking an int parameter.
|
// The free function taking no parameters.
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
void free_int(int i)
|
void free_void()
|
||||||
{
|
|
||||||
function_called = true;
|
|
||||||
parameter_correct = (i == VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// The free function taking a Data reference parameter.
|
|
||||||
//*****************************************************************************
|
|
||||||
void free_reference(const Data& data)
|
|
||||||
{
|
|
||||||
function_called = true;
|
|
||||||
parameter_correct = (data.d == VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// The test class with member functions.
|
|
||||||
//*****************************************************************************
|
|
||||||
class Test
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
void member_void()
|
|
||||||
{
|
{
|
||||||
function_called = true;
|
function_called = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void member_int(int i)
|
//*****************************************************************************
|
||||||
|
// The free function taking an int parameter.
|
||||||
|
//*****************************************************************************
|
||||||
|
void free_int(int i)
|
||||||
{
|
{
|
||||||
function_called = true;
|
function_called = true;
|
||||||
parameter_correct = (i == VALUE);
|
parameter_correct = (i == VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void member_reference(const Data& data)
|
//*****************************************************************************
|
||||||
|
// The free function taking a Data reference parameter.
|
||||||
|
//*****************************************************************************
|
||||||
|
void free_reference(const Data& data)
|
||||||
{
|
{
|
||||||
function_called = true;
|
function_called = true;
|
||||||
parameter_correct = (data.d == VALUE);
|
parameter_correct = (data.d == VALUE);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Test test_static;
|
//*****************************************************************************
|
||||||
|
// The test class with member functions.
|
||||||
|
//*****************************************************************************
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void member_void()
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void member_int(int i)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (i == VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void member_reference(const Data& data)
|
||||||
|
{
|
||||||
|
function_called = true;
|
||||||
|
parameter_correct = (data.d == VALUE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Test test_static;
|
||||||
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// Initialises the test results.
|
// Initialises the test results.
|
||||||
@ -504,4 +507,4 @@ namespace
|
|||||||
CHECK(function_called);
|
CHECK(function_called);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3688,6 +3688,20 @@ namespace
|
|||||||
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_secure_after_resize_down)
|
||||||
|
{
|
||||||
|
Text text;
|
||||||
|
text.set_secure();
|
||||||
|
text.assign(STR("ABCDEF"));
|
||||||
|
|
||||||
|
Text::pointer pe = text.end();
|
||||||
|
|
||||||
|
text.resize(text.size() - 3U);
|
||||||
|
|
||||||
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3688,6 +3688,20 @@ namespace
|
|||||||
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_secure_after_resize_down)
|
||||||
|
{
|
||||||
|
Text text;
|
||||||
|
text.set_secure();
|
||||||
|
text.assign(STR("ABCDEF"));
|
||||||
|
|
||||||
|
Text::pointer pe = text.end();
|
||||||
|
|
||||||
|
text.resize(text.size() - 3U);
|
||||||
|
|
||||||
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3688,6 +3688,20 @@ namespace
|
|||||||
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST_FIXTURE(SetupFixture, test_secure_after_resize_down)
|
||||||
|
{
|
||||||
|
Text text;
|
||||||
|
text.set_secure();
|
||||||
|
text.assign(STR("ABCDEF"));
|
||||||
|
|
||||||
|
Text::pointer pe = text.end();
|
||||||
|
|
||||||
|
text.resize(text.size() - 3U);
|
||||||
|
|
||||||
|
CHECK(std::find_if(text.end(), pe, [](Text::value_type x) { return x != 0; }) == pe);
|
||||||
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
TEST_FIXTURE(SetupFixture, test_secure_after_erase)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -49,9 +49,12 @@ namespace
|
|||||||
namespace etl
|
namespace etl
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct etl::size_of<TestData>
|
struct size_of<TestData>
|
||||||
{
|
{
|
||||||
static const size_t size = 20;
|
enum
|
||||||
|
{
|
||||||
|
size = 20
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -372,6 +372,8 @@
|
|||||||
<ClInclude Include="..\..\include\etl\crc32_c.h" />
|
<ClInclude Include="..\..\include\etl\crc32_c.h" />
|
||||||
<ClInclude Include="..\..\include\etl\cumulative_moving_average.h" />
|
<ClInclude Include="..\..\include\etl\cumulative_moving_average.h" />
|
||||||
<ClInclude Include="..\..\include\etl\c\ecl_timer.h" />
|
<ClInclude Include="..\..\include\etl\c\ecl_timer.h" />
|
||||||
|
<ClInclude Include="..\..\include\etl\delegate.h" />
|
||||||
|
<ClInclude Include="..\..\include\etl\delegate_service.h" />
|
||||||
<ClInclude Include="..\..\include\etl\format_spec.h" />
|
<ClInclude Include="..\..\include\etl\format_spec.h" />
|
||||||
<ClInclude Include="..\..\include\etl\frame_check_sequence.h" />
|
<ClInclude Include="..\..\include\etl\frame_check_sequence.h" />
|
||||||
<ClInclude Include="..\..\include\etl\fsm.h" />
|
<ClInclude Include="..\..\include\etl\fsm.h" />
|
||||||
@ -582,6 +584,8 @@
|
|||||||
<ClCompile Include="..\test_alignment.cpp" />
|
<ClCompile Include="..\test_alignment.cpp" />
|
||||||
<ClCompile Include="..\test_callback_service.cpp" />
|
<ClCompile Include="..\test_callback_service.cpp" />
|
||||||
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
|
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
|
||||||
|
<ClCompile Include="..\test_delegate.cpp" />
|
||||||
|
<ClCompile Include="..\test_delegate_service.cpp" />
|
||||||
<ClCompile Include="..\test_forward_list_shared_pool.cpp" />
|
<ClCompile Include="..\test_forward_list_shared_pool.cpp" />
|
||||||
<ClCompile Include="..\test_bit_stream.cpp" />
|
<ClCompile Include="..\test_bit_stream.cpp" />
|
||||||
<ClCompile Include="..\test_list_shared_pool.cpp" />
|
<ClCompile Include="..\test_list_shared_pool.cpp" />
|
||||||
|
|||||||
@ -768,6 +768,12 @@
|
|||||||
<ClInclude Include="..\..\include\etl\multi_array.h">
|
<ClInclude Include="..\..\include\etl\multi_array.h">
|
||||||
<Filter>ETL\Containers</Filter>
|
<Filter>ETL\Containers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\include\etl\delegate.h">
|
||||||
|
<Filter>ETL\Utilities</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\include\etl\delegate_service.h">
|
||||||
|
<Filter>ETL\Frameworks</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\main.cpp">
|
<ClCompile Include="..\main.cpp">
|
||||||
@ -1220,6 +1226,12 @@
|
|||||||
<ClCompile Include="..\test_multi_array.cpp">
|
<ClCompile Include="..\test_multi_array.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\test_delegate.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\test_delegate_service.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\library.properties">
|
<None Include="..\..\library.properties">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user