1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   filter.hpp
9  * \author Andrey Semashev
10  * \date   13.07.2012
11  *
12  * The header contains a filter function object definition.
13  */
14 
15 #ifndef BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
16 #define BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
17 
18 #include <boost/move/core.hpp>
19 #include <boost/move/utility_core.hpp>
20 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
21 #include <boost/type_traits/is_same.hpp>
22 #include <boost/type_traits/remove_cv.hpp>
23 #include <boost/log/detail/sfinae_tools.hpp>
24 #endif
25 #include <boost/log/detail/config.hpp>
26 #include <boost/log/attributes/attribute_value_set.hpp>
27 #include <boost/log/detail/light_function.hpp>
28 #include <boost/log/detail/header.hpp>
29 
30 #ifdef BOOST_HAS_PRAGMA_ONCE
31 #pragma once
32 #endif
33 
34 namespace boost {
35 
36 BOOST_LOG_OPEN_NAMESPACE
37 
38 /*!
39  * Log record filter function wrapper.
40  */
41 class filter
42 {
43     BOOST_COPYABLE_AND_MOVABLE(filter)
44 
45 public:
46     //! Result type
47     typedef bool result_type;
48 
49 private:
50     //! Filter function type
51     typedef boost::log::aux::light_function< bool (attribute_value_set const&) > filter_type;
52 
53     //! Default filter, always returns \c true
54     struct default_filter
55     {
56         typedef bool result_type;
operator ()boost::filter::default_filter57         result_type operator() (attribute_value_set const&) const { return true; }
58     };
59 
60 private:
61     //! Filter function
62     filter_type m_Filter;
63 
64 public:
65     /*!
66      * Default constructor. Creates a filter that always returns \c true.
67      */
filter()68     filter() : m_Filter(default_filter())
69     {
70     }
71     /*!
72      * Copy constructor
73      */
filter(filter const & that)74     filter(filter const& that) : m_Filter(that.m_Filter)
75     {
76     }
77     /*!
78      * Move constructor. The moved-from filter is left in an unspecified state.
79      */
filter(BOOST_RV_REF (filter)that)80     filter(BOOST_RV_REF(filter) that) BOOST_NOEXCEPT : m_Filter(boost::move(that.m_Filter))
81     {
82     }
83 
84     /*!
85      * Initializing constructor. Creates a filter which will invoke the specified function object.
86      */
87 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
88     template< typename FunT >
filter(FunT && fun)89     filter(FunT&& fun) : m_Filter(boost::forward< FunT >(fun))
90     {
91     }
92 #elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600
93     template< typename FunT >
filter(FunT const & fun,typename boost::disable_if_c<move_detail::is_rv<FunT>::value,boost::log::aux::sfinae_dummy>::type=boost::log::aux::sfinae_dummy ())94     filter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Filter(fun)
95     {
96     }
97 #else
98     // MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation
99     template< typename FunT >
filter(FunT const & fun)100     filter(FunT const& fun) : m_Filter(fun)
101     {
102     }
103     template< typename FunT >
filter(rv<FunT> & fun)104     filter(rv< FunT >& fun) : m_Filter(fun)
105     {
106     }
107     template< typename FunT >
filter(rv<FunT> const & fun)108     filter(rv< FunT > const& fun) : m_Filter(static_cast< FunT const& >(fun))
109     {
110     }
filter(rv<filter> const & that)111     filter(rv< filter > const& that) : m_Filter(that.m_Filter)
112     {
113     }
114 #endif
115 
116     /*!
117      * Move assignment. The moved-from filter is left in an unspecified state.
118      */
operator =(BOOST_RV_REF (filter)that)119     filter& operator= (BOOST_RV_REF(filter) that) BOOST_NOEXCEPT
120     {
121         m_Filter.swap(that.m_Filter);
122         return *this;
123     }
124     /*!
125      * Copy assignment.
126      */
operator =(BOOST_COPY_ASSIGN_REF (filter)that)127     filter& operator= (BOOST_COPY_ASSIGN_REF(filter) that)
128     {
129         m_Filter = that.m_Filter;
130         return *this;
131     }
132     /*!
133      * Initializing assignment. Sets the specified function object to the filter.
134      */
135 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
136     template< typename FunT >
operator =(FunT const & fun)137     filter& operator= (FunT const& fun)
138 #else
139     template< typename FunT >
140     typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, filter >::value, filter& >::type
141     operator= (FunT const& fun)
142 #endif
143     {
144         filter(fun).swap(*this);
145         return *this;
146     }
147 
148     /*!
149      * Filtering operator.
150      *
151      * \param values Attribute values of the log record.
152      * \return \c true if the log record passes the filter, \c false otherwise.
153      */
operator ()(attribute_value_set const & values) const154     result_type operator() (attribute_value_set const& values) const
155     {
156         return m_Filter(values);
157     }
158 
159     /*!
160      * Resets the filter to the default. The default filter always returns \c true.
161      */
reset()162     void reset()
163     {
164         m_Filter = default_filter();
165     }
166 
167     /*!
168      * Swaps two filters
169      */
swap(filter & that)170     void swap(filter& that) BOOST_NOEXCEPT
171     {
172         m_Filter.swap(that.m_Filter);
173     }
174 };
175 
swap(filter & left,filter & right)176 inline void swap(filter& left, filter& right) BOOST_NOEXCEPT
177 {
178     left.swap(right);
179 }
180 
181 BOOST_LOG_CLOSE_NAMESPACE // namespace log
182 
183 } // namespace boost
184 
185 #include <boost/log/detail/footer.hpp>
186 
187 #endif // BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
188