Simple-Log  alpha-v0.7
Filters.hpp
Go to the documentation of this file.
1 // Copyright Dominic Koepke 2021 - 2021.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // https://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef SL_LOG_FILTERS_HPP
7 #define SL_LOG_FILTERS_HPP
8 
9 #pragma once
10 
11 #include "Record.hpp"
12 #include "TupleAlgorithms.hpp"
13 
14 #include <algorithm>
15 #include <concepts>
16 #include <functional>
17 #include <tuple>
18 #include <type_traits>
19 
20 namespace sl::log
21 {
38  template <class TProjection, class TUnaryPredicate>
40  {
41  public:
42  using Projection_t = std::remove_cvref_t<TProjection>;
43  using UnaryPredicate_t = std::remove_cvref_t<TUnaryPredicate>;
44 
50  constexpr ProjectionFilter(
51  TProjection projection,
52  TUnaryPredicate predicate
53  )
54  noexcept(std::is_nothrow_move_constructible_v<Projection_t> && std::is_nothrow_move_constructible_v<UnaryPredicate_t>) :
55  m_Projection{ std::move(projection) },
56  m_Predicate{ std::move(predicate) }
57  {
58  }
59 
66  template <Record TRecord>
67  constexpr bool operator ()(const TRecord& rec)
68  {
69  return std::invoke(m_Predicate, std::invoke(m_Projection, rec));
70  }
71 
72  private:
73  Projection_t m_Projection;
74  UnaryPredicate_t m_Predicate;
75  };
76 
83  template <class TAlgorithm, class... TFilter>
85  {
86  public:
87  using Algorithm_t = std::remove_cvref_t<TAlgorithm>;
88 
93  constexpr explicit FilterChain(
94  TFilter ...filter
95  )
96  noexcept(std::is_nothrow_constructible_v<Algorithm_t> && (std::is_nothrow_move_constructible_v<TFilter> && ...)) :
97  m_Algorithm{},
98  m_Filter{ std::move(filter)... }
99  {
100  }
101 
107  constexpr explicit FilterChain(
108  TAlgorithm algorithm,
109  TFilter ...filter
110  ) noexcept(std::is_nothrow_move_constructible_v<Algorithm_t> && (std::is_nothrow_move_constructible_v<TFilter> && ...)) :
111  m_Algorithm{ std::move(algorithm) },
112  m_Filter{ std::forward<TFilter>(filter)... }
113  {
114  }
115 
122  template <Record TRecord>
123  constexpr bool operator()(const TRecord& rec)
124  {
125  return std::invoke(m_Algorithm, m_Filter, rec);
126  }
127 
132  [[nodiscard]]
133  constexpr bool empty() const noexcept
134  {
135  return std::tuple_size_v<decltype(m_Filter)> == 0;
136  }
137 
142  [[nodiscard]]
143  constexpr std::size_t size() const noexcept
144  {
145  return std::tuple_size_v<decltype(m_Filter)>;
146  }
147 
148  private:
149  Algorithm_t m_Algorithm;
150  std::tuple<TFilter...> m_Filter;
151  };
152 
153  //ToDo: Clang currently doesn't support alias CTAD: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1814r0.html
154  //template <std::predicate<const Record&>... TFilter>
155  //using FilterDisjunction = FilterChain<FilterAllOf, TFilter...>;
156  //
157  //template <std::predicate<const Record&>... TFilter>
158  //using FilterConjunction = FilterChain<FilterAnyOf, TFilter...>;
159 
164  template <class... TFilter>
165  class FilterAllOf :
166  public FilterChain<detail::TupleAllOf, TFilter...>
167  {
168  using Algorithm_t = detail::TupleAllOf;
169 
170  public:
175  constexpr explicit FilterAllOf(
176  TFilter ... filter
177  )
178  noexcept((std::is_nothrow_move_constructible_v<TFilter> && ...)) :
179  FilterChain<Algorithm_t, TFilter...>{ std::move(filter)... }
180  {
181  }
182  };
183 
188  template <class... TFilter>
189  class FilterAnyOf :
190  public FilterChain<detail::TupleAnyOf, TFilter...>
191  {
192  using Algorithm_t = detail::TupleAnyOf;
193 
194  public:
199  constexpr explicit FilterAnyOf(
200  TFilter ... filter
201  )
202  noexcept((std::is_nothrow_move_constructible_v<TFilter> && ...)) :
203  FilterChain<Algorithm_t, TFilter...>{ std::move(filter)... }
204  {
205  }
206  };
207 
212  template <class... TFilter>
213  class FilterNoneOf :
214  public FilterChain<detail::TupleNoneOf, TFilter...>
215  {
216  using Algorithm_t = detail::TupleNoneOf;
217 
218  public:
223  constexpr explicit FilterNoneOf(
224  TFilter ... filter
225  )
226  noexcept((std::is_nothrow_move_constructible_v<TFilter> && ...)) :
227  FilterChain<Algorithm_t, TFilter...>{ std::move(filter)... }
228  {
229  }
230  };
231 
242  template <Record TRecord, std::predicate<const RecordMessage_t<TRecord>&> TUnaryPredicate>
243  constexpr auto makeMessageFilterFor(TUnaryPredicate&& predicate)
244  {
245  return ProjectionFilter{ RecordGetters<TRecord>::message, std::forward<TUnaryPredicate>(predicate) };
246  }
247 
258  template <Record TRecord, std::predicate<const RecordSeverity_t<TRecord>&> TUnaryPredicate>
259  constexpr auto makeSeverityFilterFor(TUnaryPredicate&& predicate)
260  {
261  return ProjectionFilter{ RecordGetters<TRecord>::severity, std::forward<TUnaryPredicate>(predicate) };
262  }
263 
274  template <Record TRecord, std::predicate<const RecordChannel_t<TRecord>&> TUnaryPredicate>
275  constexpr auto makeChannelFilterFor(TUnaryPredicate&& predicate)
276  {
277  return ProjectionFilter{ RecordGetters<TRecord>::channel, std::forward<TUnaryPredicate>(predicate) };
278  }
279 
290  template <Record TRecord, std::predicate<const RecordTimePoint_t<TRecord>&> TUnaryPredicate>
291  constexpr auto makeTimePointFilterFor(TUnaryPredicate&& predicate)
292  {
293  return ProjectionFilter{ RecordGetters<TRecord>::timePoint, std::forward<TUnaryPredicate>(predicate) };
294  }
295 
297 }
298 
299 #endif
Convenience type for chaining multiple filter with AND.
Definition: Filters.hpp:167
constexpr FilterAllOf(TFilter ... filter) noexcept((std::is_nothrow_move_constructible_v< TFilter > &&...))
Constructor.
Definition: Filters.hpp:175
Convenience type for chaining multiple filter with OR.
Definition: Filters.hpp:191
constexpr FilterAnyOf(TFilter ... filter) noexcept((std::is_nothrow_move_constructible_v< TFilter > &&...))
Constructor.
Definition: Filters.hpp:199
Chains multiple filter together.
Definition: Filters.hpp:85
constexpr std::size_t size() const noexcept
Obtains the amount of attached sub-filters.
Definition: Filters.hpp:143
constexpr FilterChain(TAlgorithm algorithm, TFilter ...filter) noexcept(std::is_nothrow_move_constructible_v< Algorithm_t > &&(std::is_nothrow_move_constructible_v< TFilter > &&...))
Constructor overload.
Definition: Filters.hpp:107
std::remove_cvref_t< TAlgorithm > Algorithm_t
Definition: Filters.hpp:87
constexpr FilterChain(TFilter ...filter) noexcept(std::is_nothrow_constructible_v< Algorithm_t > &&(std::is_nothrow_move_constructible_v< TFilter > &&...))
Constructor.
Definition: Filters.hpp:93
constexpr bool operator()(const TRecord &rec)
Call-operator.
Definition: Filters.hpp:123
constexpr bool empty() const noexcept
Returns whether the are no sub-filters attached.
Definition: Filters.hpp:133
Convenience type for chaining multiple filter with NOR.
Definition: Filters.hpp:215
constexpr FilterNoneOf(TFilter ... filter) noexcept((std::is_nothrow_move_constructible_v< TFilter > &&...))
Constructor.
Definition: Filters.hpp:223
Combines a projection on Record type with a predicate into an invokable object.
Definition: Filters.hpp:40
std::remove_cvref_t< TProjection > Projection_t
Definition: Filters.hpp:42
constexpr bool operator()(const TRecord &rec)
Call-operator.
Definition: Filters.hpp:67
std::remove_cvref_t< TUnaryPredicate > UnaryPredicate_t
Definition: Filters.hpp:43
constexpr ProjectionFilter(TProjection projection, TUnaryPredicate predicate) noexcept(std::is_nothrow_move_constructible_v< Projection_t > &&std::is_nothrow_move_constructible_v< UnaryPredicate_t >)
Constructor.
Definition: Filters.hpp:50
constexpr auto makeMessageFilterFor(TUnaryPredicate &&predicate)
Factory function for creating ProjectionFilter of Record::message member.
Definition: Filters.hpp:243
constexpr auto makeSeverityFilterFor(TUnaryPredicate &&predicate)
Factory function for creating ProjectionFilter of Record::severity member.
Definition: Filters.hpp:259
constexpr auto makeTimePointFilterFor(TUnaryPredicate &&predicate)
Factory function for creating ProjectionFilter of Record::timePoint member.
Definition: Filters.hpp:291
constexpr auto makeChannelFilterFor(TUnaryPredicate &&predicate)
Factory function for creating ProjectionFilter of Record::channel member.
Definition: Filters.hpp:275
Definition: BasicSink.hpp:22
Provides a layer of abstraction to Record member setter.
Definition: Record.hpp:118