mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Added some design pattern documentation
Modified some of the layout files Modified the About documentation
This commit is contained in:
parent
5e2a789b23
commit
3dcff26123
@ -8,10 +8,6 @@ type: hextra-home
|
||||
**This documentation is still under development, and very much incomplete.**
|
||||
{{< /callout >}}
|
||||
|
||||
{{< callout emoji="❓">}}
|
||||
[***Is the ETL free?***]({{< ref "Is the ETL free.md" >}})
|
||||
{{< /callout >}}
|
||||
|
||||
<div class="not-prose badges">
|
||||
|
||||
<div>
|
||||
@ -122,8 +118,12 @@ Continuous integration via GitHub Actions.
|
||||
## Support the ETL
|
||||
Maintaining the ETL can take a lot of man-hours of work, but unfortunately it doesn't pay the bills. When I have to take on paying work, the ETL gets a lot less attention. So if you have found the library is an important component in your work and you would like to help out, then please consider by supporting the project.
|
||||
|
||||
---
|
||||
|
||||
[**Is the ETL free?**]({{< relref "is the ETL free.md" >}})
|
||||
|
||||
---
|
||||
|
||||
Any help porting the library to work under different platforms and compilers would be gratefully received.
|
||||
I am especially interested in people who are using Keil, IAR, Green Hills, TI Code Composer etc, bare metal
|
||||
or RTOS, and DSPs.
|
||||
|
||||
@ -3,6 +3,14 @@ title: "About"
|
||||
weight: 3002
|
||||
---
|
||||
|
||||
## About me
|
||||
I have been involved in technology and computer systems for all of my working life and have amassed considerable knowledge of designing and implementing systems that are both performant and correct.
|
||||
My role normally encompasses the entire project life-cycle, from specification to maintenance phase.
|
||||
|
||||
Most systems I have worked on have required high speed and deterministic performance, often within a highly constrained platform. I am experienced in designing and adapting algorithms to solutions that are both space and time efficient, avoiding the normal overheads of standard solutions.
|
||||
|
||||
Acting as a mentor for colleagues has often been a significant, though unofficial, part of my role.
|
||||
|
||||
## Why write this library?
|
||||
I wrote this library, and all the others I have written over the
|
||||
years, because I'm lazy.
|
||||
@ -46,11 +54,3 @@ The application is liable to have a close coupling with the solution. For exampl
|
||||
|
||||
I spent 12 years programming in pure C.
|
||||
I discovered that I had been reverse engineering C++ all that time.
|
||||
|
||||
## About me
|
||||
I have been involved in technology and computer systems for all of my working life and have amassed considerable knowledge of designing and implementing systems that are both performant and correct.
|
||||
My role normally encompasses the entire project life-cycle, from specification to maintenance phase.
|
||||
|
||||
Most systems I have worked on have required high speed and deterministic performance, often within a highly constrained platform. I am experienced in designing and adapting algorithms to solutions that are both space and time efficient, avoiding the normal overheads of standard solutions.
|
||||
|
||||
Acting as a mentor for colleagues has often been a significant, though unofficial, part of my role.
|
||||
|
||||
6
docs/patterns/_index.md
Normal file
6
docs/patterns/_index.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Design Patterns"
|
||||
weight: 100
|
||||
---
|
||||
|
||||
Templated implementations of common design patterns
|
||||
120
docs/patterns/observer.md
Normal file
120
docs/patterns/observer.md
Normal file
@ -0,0 +1,120 @@
|
||||
---
|
||||
title: "observer"
|
||||
---
|
||||
|
||||
A set of template classes to enable the easy creation of objects using the [Observer Pattern](https://refactoring.guru/design-patterns/observer).
|
||||
|
||||
The observer pattern is a software design pattern in which an object maintains a list of observers, and notifies of any changes. It is often used to implement event handling systems.
|
||||
|
||||
There are two templated classes:-
|
||||
|
||||
## observer
|
||||
Derive observers from this class.
|
||||
|
||||
**C++03**
|
||||
Up to eight different notification messages may be defined.
|
||||
|
||||
```cpp
|
||||
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
|
||||
class observer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
**C++11 and above**
|
||||
Any number of notification messages may be defined.
|
||||
|
||||
```cpp
|
||||
template <typename... Types>
|
||||
class observer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
`observer` defines a pure virtual notification member function for each defined type, taking the type as a parameter.
|
||||
The parameter type may be `void` (Since `20.39.0`).
|
||||
Derived classes are forced to implement these functions.
|
||||
|
||||
**Example**
|
||||
|
||||
```cpp
|
||||
// An observer type that handles int (by value), std::string (by reference)
|
||||
// and std::complex (by const reference).
|
||||
typedef etl::observer<int, std::string&, const std::complex&> observer_type;
|
||||
|
||||
class my_observer : public observer_type
|
||||
{
|
||||
public:
|
||||
void notification(int i);
|
||||
void notification(std::string& s);
|
||||
void notification(const std::complex);
|
||||
};
|
||||
```
|
||||
|
||||
## observable
|
||||
This class is observable from a class derived from `observer`.
|
||||
Derive observable classes from this.
|
||||
|
||||
```cpp
|
||||
template <typename TObserver, const size_t MAX_OBSERVERS>
|
||||
class observable
|
||||
```
|
||||
|
||||
```cpp
|
||||
void add_observer(TObserver& observer)
|
||||
```
|
||||
**Description**
|
||||
Adds an observer to the list. If the maximum number of observers have already been added then an `etl::observer_list_full` is emitted.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void remove_observer(TObserver& observer)
|
||||
```
|
||||
Remove an observer from the list. If the observer is not in the list then there is no change.
|
||||
Do not call this from within a notification override.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void enable_observer(TObserver& observer, bool state = true)
|
||||
```
|
||||
Enables / disables an observer according to the parameter value.
|
||||
The default is `true`.
|
||||
May be called from a notification override.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void disable_observer(TObserver& observer)
|
||||
```
|
||||
Disables an observer from being called from notify_observers.
|
||||
May be called from a notification override.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void clear_observers()
|
||||
```
|
||||
Removes all observers from the list.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
size_type number_of_observers() const
|
||||
```
|
||||
Returns the number of observers currently in the list.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename TNotification>
|
||||
void notify_observers(TNotification data)
|
||||
```
|
||||
By default, the parameter is passed by as the actual data.
|
||||
To pass by reference or rvalue reference, add the type as a template parameter.
|
||||
```cpp
|
||||
notify_observers<const MyData&>(data);
|
||||
```
|
||||
@ -1,24 +1,36 @@
|
||||
Overload
|
||||
20.14.0
|
||||
For C++17 and above
|
||||
---
|
||||
title: "overload"
|
||||
---
|
||||
|
||||
Allows creation of a functor of overloaded lambdas
|
||||
{{< callout type="info">}}
|
||||
Header: `overload.h`
|
||||
Since: `20.14.0`
|
||||
{{< /callout >}}
|
||||
|
||||
**For C++17 and above**
|
||||
|
||||
Allows creation of a functor of overloaded lambdas.
|
||||
|
||||
```cpp
|
||||
etl::overload<typename... TOverloads>
|
||||
____________________________________________________________________________________________________
|
||||
Template deduction guide
|
||||
```
|
||||
|
||||
## Template deduction guide
|
||||
|
||||
template <typename... TOverloads>
|
||||
overload(TOverloads...) -> overload<TOverloads...>;
|
||||
____________________________________________________________________________________________________
|
||||
Non-member functions
|
||||
|
||||
## Non-member functions
|
||||
|
||||
```cpp
|
||||
template <typename... TOverloads>
|
||||
constexpr overload<TOverloads...> make_overload(TOverloads&&... overloads)
|
||||
Creates an etl::overload from a set of lambdas.
|
||||
____________________________________________________________________________________________________
|
||||
Example
|
||||
```
|
||||
Creates an `etl::overload` from a set of lambdas.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
int result_int;
|
||||
double result_double;
|
||||
std::string result_string;
|
||||
@ -36,13 +48,16 @@ void Function(T value, TOverload&& ol)
|
||||
Function(int(1), overloaded); // result_int == 1
|
||||
Function(double(2.2), overloaded); // result_double == 2.2
|
||||
Function(std::string("3"), overloaded); // result_string == "3"
|
||||
____________________________________________________________________________________________________
|
||||
Alternative syntax
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Alternative syntax**
|
||||
```cpp
|
||||
Function(int(1), etl::overload
|
||||
{
|
||||
[](int i) { result_int = i; },
|
||||
[](double d) { result_double = d; },
|
||||
[](const std::string& s) { result_string = s; }
|
||||
});
|
||||
|
||||
|
||||
```
|
||||
216
docs/patterns/successor.md
Normal file
216
docs/patterns/successor.md
Normal file
@ -0,0 +1,216 @@
|
||||
---
|
||||
title: "successor"
|
||||
---
|
||||
|
||||
{{< callout type="info">}}
|
||||
Header: `successor.h`
|
||||
{{< /callout >}}
|
||||
|
||||
Adds successor traits to a derived class.
|
||||
This template adds the ability for a class to store a successor to itself which allows the [Chain of Responsibility](https://refactoring.guru/design-patterns/chain-of-responsibility) design pattern to be implemented in a consistent fashion.
|
||||
|
||||
**Note:**
|
||||
The successors do not have to be derived from `etl::successor`, but the member functions `append_successor` and `clear_successor_chain` cannot be used if they are not.
|
||||
|
||||
```cpp
|
||||
etl::successor<typename T>
|
||||
```
|
||||
`T` The successor type.
|
||||
|
||||
|
||||
## Member types
|
||||
```cpp
|
||||
successor_type T
|
||||
```
|
||||
|
||||
## Constructors
|
||||
```cpp
|
||||
successor()
|
||||
```
|
||||
Constructs a default successor.
|
||||
`has_successor()` will return `false`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
successor(successor_type& s)
|
||||
```
|
||||
Constructs a successor from the supplied parameter `s`.
|
||||
`has_successor()` will return `true`.
|
||||
|
||||
## Member functions
|
||||
```cpp
|
||||
void set_successor(successor_type& s)
|
||||
```
|
||||
Sets the successor to `s`.
|
||||
Overwrites any previous successor.
|
||||
`has_successor()` will return `true`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename... TSuccessors>
|
||||
void set_successor(successor_type& s, TSuccessors&... rest)
|
||||
```
|
||||
Sets a series of successors to `s`.
|
||||
Overwrites any previous successor.
|
||||
Since `20.28.0`, C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename TSuccessor>
|
||||
void append_successor(TSuccessor& s)
|
||||
```
|
||||
Appends the successor to the end of the successor chain.
|
||||
Only valid to call if all successors are derived from `etl::successor`.
|
||||
Since `20.28.0`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
template <typename TSuccessor, typename... TSuccessors>
|
||||
void append_successor(TSuccessor& s, TSuccessors&... rest)
|
||||
```
|
||||
Appends the list of successors to the end of the successor chain.
|
||||
Only valid to call if all successors are derived from `etl::successor`.
|
||||
Since `20.28.0`, C++11.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
successor_type& get_successor() const
|
||||
```
|
||||
Gets a reference to the successor.
|
||||
Undefined behaviour if a successor has not been set.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
bool has_successor() const
|
||||
```
|
||||
Returns `true` if a successor has been set.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void clear_successor()
|
||||
```
|
||||
Clears the successor.
|
||||
`has_successor()` will return `false`.
|
||||
Since `20.28.0`.
|
||||
|
||||
---
|
||||
|
||||
```cpp
|
||||
void clear_successor_chain()
|
||||
```
|
||||
Clears the successor for every successor in the chain starting from this successor.
|
||||
Only valid to call if all successors are derived from `etl::successor`.
|
||||
Since `20.28.0`.
|
||||
|
||||
## Error types
|
||||
`successor_exception` Derived from `etl::exception`
|
||||
`successor_invalid` Derived from `successor_exception`
|
||||
|
||||
|
||||
## Example
|
||||
```cpp
|
||||
class IProcessor : public etl::successor<IProcessor>
|
||||
{
|
||||
public:
|
||||
|
||||
//*********************************
|
||||
virtual bool Check() = 0;
|
||||
|
||||
//*********************************
|
||||
// Step though the successors until either the
|
||||
// call is handled, or there are no successors left.
|
||||
bool Process()
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
IProcessor* p = this;
|
||||
|
||||
while (handled == false)
|
||||
{
|
||||
handled = p->Check();
|
||||
|
||||
// Were we unable to handle call?
|
||||
if (handled == false)
|
||||
{
|
||||
// Do we have a successor?
|
||||
if (p->has_successor())
|
||||
{
|
||||
// Get the next successor.
|
||||
p = &(p->get_successor());
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have reached the end of the chain.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor1 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor2 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor3 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor4 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Processor1 processor1a;
|
||||
Processor1 processor1b;
|
||||
Processor2 processor2a;
|
||||
Processor2 processor2b;
|
||||
Processor3 processor3;
|
||||
Processor4 processor4;
|
||||
|
||||
processor1a.append_successor(processor2a, processor3);
|
||||
processor1b.append_successor(processor2b, processor4);
|
||||
|
||||
bool b1a = processor1a.Process(); // Returns false, nothing handles the process call.
|
||||
bool b1b = processor1b.Process(); // Returns true, processor4 handles the process call.
|
||||
```
|
||||
@ -1,76 +0,0 @@
|
||||
Observer
|
||||
A set of template classes to enable the easy creation of objects using the Observer pattern.
|
||||
|
||||
The observer pattern is a software design pattern in which an object maintains a list of observers, and notifies of any changes. It is often used to implement event handling systems. See the tutorial.
|
||||
|
||||
There are two templated classes:-
|
||||
____________________________________________________________________________________________________
|
||||
observer
|
||||
Derive observers from this class.
|
||||
|
||||
C++03
|
||||
Up to eight different notification messages may be defined.
|
||||
|
||||
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
|
||||
class observer
|
||||
|
||||
C++11 and above
|
||||
Any number of notification messages may be defined.
|
||||
|
||||
template <typename... Types>
|
||||
class observer
|
||||
____________________________________________________________________________________________________
|
||||
observer defines a pure virtual notification member function for each defined type, taking the type as a parameter.
|
||||
The parameter type may be void (20.39.0).
|
||||
Derived classes are forced to implement these functions.
|
||||
|
||||
Example:-
|
||||
|
||||
// An observer type that handles int (by value), std::string (by reference)
|
||||
// and std::complex (by const reference).
|
||||
typedef etl::observer<int, std::string&, const std::complex&> observer_type;
|
||||
|
||||
class my_observer : public observer_type
|
||||
{
|
||||
public:
|
||||
void notification(int i);
|
||||
void notification(std::string& s);
|
||||
void notification(const std::complex);
|
||||
};
|
||||
____________________________________________________________________________________________________
|
||||
observable
|
||||
This class is observable from a class derived from observer.
|
||||
Derive observable classes from this.
|
||||
|
||||
template <typename TObserver, const size_t MAX_OBSERVERS>
|
||||
class observable
|
||||
____________________________________________________________________________________________________
|
||||
void add_observer(TObserver& observer)
|
||||
Adds an observer to the list. If the maximum number of observers have already been added then an etl::observer_list_full is emitted.
|
||||
____________________________________________________________________________________________________
|
||||
void remove_observer(TObserver& observer)
|
||||
Remove an observer from the list. If the observer is not in the list then there is no change.
|
||||
Do not call this from within a notification override.
|
||||
____________________________________________________________________________________________________
|
||||
void enable_observer(TObserver& observer, bool state = true)
|
||||
Enables / disables an observer according to the parameter value.
|
||||
The default is true.
|
||||
May be called from a notification override.
|
||||
____________________________________________________________________________________________________
|
||||
void disable_observer(TObserver& observer)
|
||||
Disables an observer from being called from notify_observers.
|
||||
May be called from a notification override.
|
||||
____________________________________________________________________________________________________
|
||||
void clear_observers()
|
||||
Removes all observers from the list.
|
||||
____________________________________________________________________________________________________
|
||||
size_type number_of_observers() const
|
||||
Returns the number of observers currently in the list.
|
||||
____________________________________________________________________________________________________
|
||||
template <typename TNotification>
|
||||
void notify_observers(TNotification data)
|
||||
By default, the parameter is passed by as the actual data .
|
||||
To pass by reference or rvalue reference, add the type as a template parameter.
|
||||
notify_observers<const MyData&>(data);
|
||||
|
||||
@ -1,174 +0,0 @@
|
||||
Successor
|
||||
|
||||
Adds successor traits to a derived class.
|
||||
This template adds the ability for a class to store a successor to itself which allows the 'Chain of Responsibility' design pattern to be implemented in a consistent fashion.
|
||||
|
||||
Note:
|
||||
The successors do not have to be derived from etl::successor, but the member functions append_successor and clear_successor_chain cannot be used if they are not.
|
||||
|
||||
etl::successor<typename T>
|
||||
T The successor type
|
||||
____________________________________________________________________________________________________
|
||||
Member types
|
||||
|
||||
successor_type T
|
||||
____________________________________________________________________________________________________
|
||||
Constructors
|
||||
|
||||
successor()
|
||||
Constructs a default successor.
|
||||
has_successor() will return false.
|
||||
____________________________________________________________________________________________________
|
||||
successor(successor_type& s)
|
||||
Constructs a successor from the supplied parameter s.
|
||||
has_successor() will return true.
|
||||
____________________________________________________________________________________________________
|
||||
Member functions
|
||||
|
||||
void set_successor(successor_type& s)
|
||||
Sets the successor to s.
|
||||
Overwrites any previous successor.
|
||||
has_successor() will return true.
|
||||
____________________________________________________________________________________________________
|
||||
template <typename... TSuccessors>
|
||||
void set_successor(successor_type& s, TSuccessors&... rest)
|
||||
Sets a series of successors to s.
|
||||
Overwrites any previous successor.
|
||||
20.28.0, C++11
|
||||
____________________________________________________________________________________________________
|
||||
template <typename TSuccessor>
|
||||
void append_successor(TSuccessor& s)
|
||||
Appends the successor to the end of the successor chain.
|
||||
Only valid to call if all successors are derived from etl::successor.
|
||||
20.28.0
|
||||
____________________________________________________________________________________________________
|
||||
template <typename TSuccessor, typename... TSuccessors>
|
||||
void append_successor(TSuccessor& s, TSuccessors&... rest)
|
||||
Appends the list of successors to the end of the successor chain.
|
||||
Only valid to call if all successors are derived from etl::successor.
|
||||
20.28.0, C++11
|
||||
____________________________________________________________________________________________________
|
||||
successor_type& get_successor() const
|
||||
Gets a reference to the successor.
|
||||
Undefined behaviour if a successor has not been set.
|
||||
____________________________________________________________________________________________________
|
||||
bool has_successor() const
|
||||
Returns true if a successor has been set.
|
||||
____________________________________________________________________________________________________
|
||||
void clear_successor()
|
||||
Clears the successor.
|
||||
has_successor() will return false.
|
||||
20.28.0
|
||||
____________________________________________________________________________________________________
|
||||
void clear_successor_chain()
|
||||
Clears the successor for every successor in the chain starting from this successor.
|
||||
Only valid to call if all successors are derived from etl::successor.
|
||||
20.28.0
|
||||
____________________________________________________________________________________________________
|
||||
Error types
|
||||
|
||||
successor_exception Derived from etl::exception
|
||||
successor_invalid Derived from successor_exception
|
||||
____________________________________________________________________________________________________
|
||||
Example
|
||||
|
||||
class IProcessor : public etl::successor<IProcessor>
|
||||
{
|
||||
public:
|
||||
|
||||
//*********************************
|
||||
virtual bool Check() = 0;
|
||||
|
||||
//*********************************
|
||||
// Step though the successors until either the
|
||||
// call is handled, or there are no successors left.
|
||||
bool Process()
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
IProcessor* p = this;
|
||||
|
||||
while (handled == false)
|
||||
{
|
||||
handled = p->Check();
|
||||
|
||||
// Were we unable to handle call?
|
||||
if (handled == false)
|
||||
{
|
||||
// Do we have a successor?
|
||||
if (p->has_successor())
|
||||
{
|
||||
// Get the next successor.
|
||||
p = &(p->get_successor());
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have reached the end of the chain.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor1 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor2 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor3 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//*********************************
|
||||
class Processor4 : public IProcessor
|
||||
{
|
||||
public:
|
||||
|
||||
bool Check() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Processor1 processor1a;
|
||||
Processor1 processor1b;
|
||||
Processor2 processor2a;
|
||||
Processor2 processor2b;
|
||||
Processor3 processor3;
|
||||
Processor4 processor4;
|
||||
|
||||
processor1a.append_successor(processor2a, processor3);
|
||||
processor1b.append_successor(processor2b, processor4);
|
||||
|
||||
bool b1a = processor1a.Process(); // Returns false, nothing handles the process call.
|
||||
bool b1b = processor1b.Process(); // Returns true, processor4 handles the process call.
|
||||
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
ETL_STATIC_ASSERT
|
||||
Either maps on to the built-in static_assert or supplies a suitable definition.
|
||||
|
||||
ETL_STATIC_ASSERT(condition, message);
|
||||
|
||||
Example
|
||||
template <typename T>
|
||||
void Do_This(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ weight: 2003
|
||||
|
||||
[Bit Twiddling Hacks](https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog)
|
||||
|
||||
[Design Patterns](https://refactoring.guru/design-patterns)
|
||||
|
||||
## Embedded Operating Systems
|
||||
|
||||
[FreeRTOS](https://freertos.org/)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<footer style="text-align: center;">
|
||||
<p>Designed and Maintained by John Wellbelove</p>
|
||||
<p>© 2014–{{ now.Format "2006" }} {{ .Site.Title }}. All rights reserved.</p>
|
||||
<p></p>
|
||||
</footer>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user