31#ifndef _LIBCPP_HAS_NO_TIME_ZONE_DATABASE
34 template<
class...T_Args>
36 template<class C_LogImpl, class C_Holder = typename C_AutoSinkHolderT<C_LogImpl>::type,
class...T_Args>
42 std::ostream *
lockLog()
override;
51 using FC_Accept = std::function<
bool(std::string_view)>;
52 using C_NodePtr = std::unique_ptr<C_Node>;
54 struct C_NodePartition
56 std::vector<std::pair<FC_Accept,C_NodePtr>> m_filteredNodes;
62 std::vector<std::unique_ptr<I_ReenterableLog>> m_loggers;
63 std::list<C_NodePartition> m_partitions;
67 struct C_LockedNodePartition;
71 std::vector<std::pair<I_ReenterableLog*,std::ostream*>> m_loggers;
72 std::vector<C_LockedNodePartition> m_partitions;
74 void create_from(
const C_Node &node,
const std::function<std::ostream*(
I_ReenterableLog&)> &to_log);
75 bool empty()
const {
return m_loggers.empty() && m_partitions.empty(); }
76 void log(std::string_view s,
bool flush)
const;
79 struct C_LockedNodePartition
81 std::vector<std::pair<const FC_Accept&,C_LockedNode>> m_filteredNodes;
82 C_LockedNode m_elseNode;
84 bool empty()
const {
return m_filteredNodes.empty() && m_elseNode.empty(); }
88 std::recursive_mutex m_lock;
90 std::list<std::pair<C_LockedNode,std::ostringstream>> m_lockedStack;
93 std::ostream *
lockLog(
const std::function<std::ostream*(I_ReenterableLog&)> &to_log);
101 C_NodeArrayProxy(std::recursive_mutex &lock, C_NodePartition &nodePart): m_lock(&lock), m_nodePart(&nodePart) {}
109 std::recursive_mutex *m_lock;
110 C_NodePartition *m_nodePart;
121 C_NodeProxy(std::recursive_mutex &lock, C_Node &node): m_lock(&lock), m_node(&node) {}
122 template<std::derived_from<I_ReenterableLog> T>
125 std::lock_guard _{*m_lock};
128 m_node->m_loggers.emplace_back(std::move(snap));
135 return addChild(std::make_unique<C_ReenterableOstream>(out, ll));
139 return addChild(std::make_unique<C_ReenterableOstreamSnap>(snap, ll));
141 template<class C_LogImpl, class C_Holder = typename C_AutoSinkHolderT<C_LogImpl>::type,
class...T_Args>
144 auto child = std::make_unique<C_ReenterableLoggerInside<C_LogImpl,C_Holder>>(ll, std::forward<T_Args>(args)...);
146 post_ctor(child->impl());
152 std::lock_guard _{*m_lock};
153 auto &dst = m_node->m_partitions.emplace_back();
154 dst.m_filteredNodes.emplace_back(std::piecewise_construct, std::forward_as_tuple(f), std::forward_as_tuple());
155 return {*m_lock, dst};
157 template<
typename Filters>
159 { *std::begin(fs) }-> std::convertible_to<FC_Accept>;
160 { std::size(fs) }-> std::convertible_to<size_t>;
164 std::lock_guard _{*m_lock};
165 auto &dst = m_node->m_partitions.emplace_back();
166 dst.m_filteredNodes.reserve(std::size(fs));
168 dst.m_filteredNodes.emplace_back(std::piecewise_construct, std::forward_as_tuple(i), std::forward_as_tuple());
170 return {*m_lock, dst};
176 std::recursive_mutex *m_lock;
183template<
class...T_Args>
189template<
class C_LogImpl,
class C_Holder,
class...T_Args>
@ LL_VERBOSE
More detailed or advanced information probably considered too much by some.
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_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)
C_ParaLog(T_LocalZone tz_=T_LocalZone())
std::ostream * lockLog() override
Return non-null pointer if possible.
I_SyncLog(T_LocalZone tz_)
THE common namespace of bux library.
@ LL_VERBOSE
More detailed or advanced information probably considered too much by some.
const std::chrono::time_zone * T_LocalZone
Thread-unsafe implementation is preferred for performance.