|
Flow 2.0.0
Flow project: Public API.
|
Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns this Logger and Component via get_logger() and get_log_component() public accessors. More...
#include <log.hpp>
Public Member Functions | |
| Log_context (Logger *logger=nullptr) | |
| Constructs Log_context by storing the given pointer to a Logger and a null Component. More... | |
| template<typename Component_payload > | |
| Log_context (Logger *logger, Component_payload component_payload) | |
Constructs Log_context by storing the given pointer to a Logger and a new Component storing the specified generically typed payload (an enum value). More... | |
| Log_context (const Log_context &src) | |
Copy constructor that stores equal Logger* and Component values as the source. More... | |
| Log_context (Log_context &&src) | |
Move constructor that makes this equal to src, while the latter becomes as-if default-constructed. More... | |
| Log_context & | operator= (const Log_context &src) |
| Assignment operator that behaves similarly to the copy constructor. More... | |
| Log_context & | operator= (Log_context &&src) |
| Move assignment operator that behaves similarly to the move constructor. More... | |
| void | swap (Log_context &other) |
Swaps Logger pointers and Component objects held by *this and other. More... | |
| Logger * | get_logger () const |
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect. More... | |
| Logger * | set_logger (Logger *logger) |
| Sets the value to be returned by the next get_logger() call; returns get_logger() from before the change. More... | |
| const Component & | get_log_component () const |
Returns reference to the stored Component object, particularly as many FLOW_LOG_*() macros expect. More... | |
Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns this Logger and Component via get_logger() and get_log_component() public accessors.
It's extremely useful (almost mandatory in conventional practice) for classes that want to log, as they can simply derive from it (passing in the desired Logger* and Component payload (an enum value) into the Log_context super-class constructor), at which point the get_logger() and get_log_component() functions the FLOW_LOG_...() macros expect automatically become available without any additional code having to be written in the logging class. Here is how:
Note that the operator=() allows one to change the underlying Logger anytime after construction (e.g., existing_log_context = Log_context{&some_logger, Some_enum::S_SOME_COMPONENT};). That said it is more convenient to use set_logger(); but see the next section, as this may involve more subtleties than one might think.
set_logger() allows one, including an external user, to change the Logger. However beware two points w/r/t thread safety.
*this = Log_context{...} concurrently with any call that would log via get_logger(): so anything that, e.g., does FLOW_LOG_...(). It only replaces a pointer in memory, but there is no mutex or atomic protection; so it is not safe.Informally: Generally it is best to avoid changing the active Logger, after an object is constructed. 99% of code in practice does not do so; it is usually far better to affect the Logger via its Config which takes massive pains to be both thread-safe and performant at that.
However in practice there is at least one exception to this: when the sub-class's instance is static or even global and/or a singleton. Then it might operate before and even after main(), and even during main() there may not be a good Logger to use yet. One might then make use of set_logger(), e.g., early in main() to change it from null to a Logger and then back late in main() (or if not null then a default Simple_ostream_logger to cout + cerr... you get the idea).
That however does not protect against thread-safety problems (point 1 above) necessarily. It depends when one does it. If it is necessary to be changing get_logger() return-value while get_logger() is potentially used by another thread, then consider using Log_context_mt. There is a bit of a perf trade-off there (see its doc header).
The code could be shorter by getting rid of non-copy constuctor in favor of direct member initialization by user; and by simply omitting the API for the auto-generated copy constructor and assignment. However, in this case, I wanted to clearly document the API; and since there are more than 1 constructors, it seemed better to explicitly declare them all instead of replacing some with implicitly required direct initialization (again to make API more clearly documented).
The only operation of interest w/r/t threads is the aforementioned implicit assignment operator. Thread safety is the same as for any struct with no locking done therein.
|
explicit |
Constructs Log_context by storing the given pointer to a Logger and a null Component.
| logger | Pointer to store. Rationale for providing the null default: To facilitate sub-class = default no-arg ctors. |
|
explicit |
Constructs Log_context by storing the given pointer to a Logger and a new Component storing the specified generically typed payload (an enum value).
For more background on Component see its doc header.
| Component_payload | See Component constructor doc header: Payload template arg specifically. |
| logger | Pointer to store. |
| component_payload | See Component constructor doc header: payload arg specifically. |
|
explicitdefault |
Copy constructor that stores equal Logger* and Component values as the source.
This is explicit, even though an unintentional copy (e.g., in a bind sans cref or ref) would just internally involve the copying a pointer (as of this writing). The reason is that it's unlikely one wants to blithely copy these objects or objects of a sub-type; most likely (at least in scenarios seen so far, as of this writing) a cref or ref is in order instead. (I am open to counter-examples and thus removing this explicit keyword if convinced by one.)
| src | Source object. |
| flow::log::Log_context::Log_context | ( | Log_context && | src | ) |
Move constructor that makes this equal to src, while the latter becomes as-if default-constructed.
| src | Source object. |
| const Component & flow::log::Log_context::get_log_component | ( | ) | const |
Returns reference to the stored Component object, particularly as many FLOW_LOG_*() macros expect.
| Logger * flow::log::Log_context::get_logger | ( | ) | const |
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect.
|
default |
Assignment operator that behaves similarly to the copy constructor.
| src | Source object. |
*this. | Log_context & flow::log::Log_context::operator= | ( | Log_context && | src | ) |
Move assignment operator that behaves similarly to the move constructor.
| src | Source object. |
*this. Sets the value to be returned by the next get_logger() call; returns get_logger() from before the change.
Behavior is undefined if invoked concurrently with itself or get_logger() on the same *this. If that is unacceptable: see our class doc header for brief discussion / suggestion on alternative to Log_context.
| logger | As in ctor. |
| void flow::log::Log_context::swap | ( | Log_context & | other | ) |