31 explicit C_ParaLog(
bool use_local_time):
C_ParaLog(use_local_time? std::chrono::get_tzdb().current_zone(): nullptr) {}
32 template<
class...T_Args>
34 template<class C_LogImpl, class C_Holder = typename C_AutoSinkHolderT<C_LogImpl>::type,
class...T_Args>
40 std::ostream *
lockLog()
override;
49 using FC_Accept = std::function<
bool(std::string_view)>;
50 using C_NodePtr = std::unique_ptr<C_Node>;
52 struct C_NodePartition
54 std::vector<std::pair<FC_Accept,C_NodePtr>> m_filteredNodes;
60 std::vector<std::unique_ptr<I_ReenterableLog>> m_loggers;
61 std::list<C_NodePartition> m_partitions;
65 struct C_LockedNodePartition;
69 std::vector<std::pair<I_ReenterableLog*,std::ostream*>> m_loggers;
70 std::vector<C_LockedNodePartition> m_partitions;
72 void create_from(
const C_Node &node,
const std::function<std::ostream*(
I_ReenterableLog&)> &to_log);
73 bool empty()
const {
return m_loggers.empty() && m_partitions.empty(); }
74 void log(std::string_view s,
bool flush)
const;
77 struct C_LockedNodePartition
79 std::vector<std::pair<const FC_Accept&,C_LockedNode>> m_filteredNodes;
80 C_LockedNode m_elseNode;
82 bool empty()
const {
return m_filteredNodes.empty() && m_elseNode.empty(); }
86 std::recursive_mutex m_lock;
88 std::list<std::pair<C_LockedNode,std::ostringstream>> m_lockedStack;
91 std::ostream *
lockLog(
const std::function<std::ostream*(I_ReenterableLog&)> &to_log);
99 C_NodeArrayProxy(std::recursive_mutex &lock, C_NodePartition &nodePart): m_lock(&lock), m_nodePart(&nodePart) {}
107 std::recursive_mutex *m_lock;
108 C_NodePartition *m_nodePart;
119 C_NodeProxy(std::recursive_mutex &lock, C_Node &node): m_lock(&lock), m_node(&node) {}
120 template<std::derived_from<I_ReenterableLog> T>
123 std::lock_guard _{*m_lock};
126 m_node->m_loggers.emplace_back(std::move(snap));
133 return addChild(std::make_unique<C_ReenterableOstream>(out, ll));
137 return addChild(std::make_unique<C_ReenterableOstreamSnap>(snap, ll));
139 template<class C_LogImpl, class C_Holder = typename C_AutoSinkHolderT<C_LogImpl>::type,
class...T_Args>
142 auto child = std::make_unique<C_ReenterableLoggerInside<C_LogImpl,C_Holder>>(ll, std::forward<T_Args>(args)...);
144 post_ctor(child->impl());
150 std::lock_guard _{*m_lock};
151 auto &dst = m_node->m_partitions.emplace_back();
152 dst.m_filteredNodes.emplace_back(std::piecewise_construct, std::forward_as_tuple(f), std::forward_as_tuple());
153 return {*m_lock, dst};
155 template<
typename Filters>
157 { *std::begin(fs) }-> std::convertible_to<FC_Accept>;
158 { std::size(fs) }-> std::convertible_to<size_t>;
162 std::lock_guard _{*m_lock};
163 auto &dst = m_node->m_partitions.emplace_back();
164 dst.m_filteredNodes.reserve(std::size(fs));
166 dst.m_filteredNodes.emplace_back(std::piecewise_construct, std::forward_as_tuple(i), std::forward_as_tuple());
168 return {*m_lock, dst};
174 std::recursive_mutex *m_lock;
181template<
class...T_Args>
187template<
class C_LogImpl,
class C_Holder,
class...T_Args>
C_NodeArrayProxy(std::recursive_mutex &lock, C_NodePartition &nodePart)
C_NodeProxy operator[](size_t i) const
size_t sizeOfFilters() const
C_NodeProxy matchedNone() const
bool addChild(I_SnapT< std::ostream * > &snap, E_LogLevel ll=LL_VERBOSE) const
bool addChild(std::unique_ptr< T > &&snap) const
bool addChildT(std::function< void(C_LogImpl &)> post_ctor={}, E_LogLevel ll=LL_VERBOSE, T_Args &&...args) const
C_NodeProxy(std::recursive_mutex &lock, C_Node &node)
C_NodeArrayProxy partitionBy(Filters fs) const
C_NodeArrayProxy partitionBy(std::convertible_to< FC_Accept > auto f) const
bool addChild(std::ostream &out, E_LogLevel ll=LL_VERBOSE) const
bool addChild(T_Args &&...args)
C_ParaLog(bool use_local_time)
C_ParaLog(const std::chrono::time_zone *tz_=nullptr)
C_NodeArrayProxy partitionBy(F f)
void unlockLog(bool flush) override
If the previous call to lockLog() returned null, the behavior is undefined.
bool addChildT(std::function< void(C_LogImpl &)> post_ctor={}, E_LogLevel ll=LL_VERBOSE, T_Args &&...args)
std::ostream * lockLog() override
Return non-null pointer if possible.
</// Thread safety is expected
THE common namespace of bux library.
@ LL_VERBOSE
More detailed or advanced information probably considered too much by some.
Thread-unsafe implementation is preferred for performance.