| /** @file |
| Meta programming support for WCCP. |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <algorithm> |
| |
| // Various meta programming efforts. Experimental at present. |
| |
| namespace ts |
| { |
| // Some support templates so we can fail to compile if the |
| // compile time check fails. |
| |
| // This creates the actual error, depending on whether X has a valid |
| // nest type Result. |
| template <typename X> struct TEST_RESULT { |
| typedef typename X::Result type; |
| }; |
| |
| // Bool checking - a base template then specializations to succeed or |
| // fail. |
| template <bool VALUE> struct TEST_BOOL { |
| }; |
| // Successful test defines Result. |
| template <> struct TEST_BOOL<true> { |
| typedef int Result; |
| }; |
| // Failing test does not define Result. |
| template <> struct TEST_BOOL<false> { |
| }; |
| |
| // Fail to compile if VALUE is not true. |
| template <bool VALUE> struct TEST_IF_TRUE : public TEST_RESULT<TEST_BOOL<VALUE>> { |
| }; |
| |
| // Helper for assigning a value to all instances in a container. |
| template <typename T, typename R, typename A1> struct TsAssignMember : public std::binary_function<T, A1, R> { |
| R T::*_m; |
| A1 _arg1; |
| TsAssignMember(R T::*m, A1 const &arg1) : _m(m), _arg1(arg1) {} |
| R |
| operator()(T &t) const |
| { |
| return t.*_m = _arg1; |
| } |
| }; |
| |
| // Helper function to compute types for TsAssignMember. |
| template <typename T, typename R, typename A1> |
| struct TsAssignMember<T, R, A1> |
| assign_member(R T::*m, A1 const &arg1) { |
| return TsAssignMember<T, R, A1>(m, arg1); |
| } |
| |
| // Overload for_each to operate on a container. |
| template <typename C, typename F> |
| void |
| for_each(C &c, F const &f) |
| { |
| std::for_each(c.begin(), c.end(), f); |
| } |
| |
| /** Calc minimal value over a direct type container. |
| This handles an accessor that takes a argument. |
| */ |
| template <typename C, typename V, typename ARG1> |
| V |
| minima(C const &c, V (C::value_type::*ex)(ARG1) const, ARG1 const &arg1) |
| { |
| V v = std::numeric_limits<V>::max(); |
| for (typename C::const_iterator spot = c.begin(), limit = c.end(); spot != limit; ++spot) { |
| v = std::min(v, ((*spot).*ex)(arg1)); |
| } |
| return v; |
| } |
| |
| /** Calc minimal value over a paired type container. |
| This handles an accessor that takes a argument. |
| */ |
| template <typename C, typename V, typename ARG1> |
| V |
| minima(C const &c, V (C::value_type::second_type::*ex)(ARG1) const, ARG1 const &arg1) |
| { |
| V v = std::numeric_limits<V>::max(); |
| for (typename C::const_iterator spot = c.begin(), limit = c.end(); spot != limit; ++spot) { |
| v = std::min(v, ((spot->second).*ex)(arg1)); |
| } |
| return v; |
| } |
| |
| /** Apply a unary method to every object in a direct container. |
| */ |
| template <typename C, typename V, typename ARG1> |
| void |
| for_each(C &c, V (C::value_type::*ex)(ARG1), ARG1 const &arg1) |
| { |
| for (typename C::iterator spot = c.begin(), limit = c.end(); spot != limit; ++spot) |
| ((*spot).*ex)(arg1); |
| } |
| |
| /** Apply a unary method to every object in a paired container. |
| */ |
| template <typename C, typename V, typename ARG1> |
| void |
| for_each(C &c, V (C::value_type::second_type::*ex)(ARG1) const, ARG1 const &arg1) |
| { |
| for (typename C::iterator spot = c.begin(), limit = c.end(); spot != limit; ++spot) |
| ((spot->second).*ex)(arg1); |
| } |
| |
| template <typename Elt, ///< Element type. |
| typename Value ///< Member value type. |
| > |
| struct MemberPredicate { |
| Value const &m_value; ///< Value to test against. |
| Value Elt::*m_mptr; ///< Pointer to member to test. |
| MemberPredicate(Value Elt::*mptr, Value const &v) : m_value(v), m_mptr(mptr) {} |
| bool |
| operator()(Elt const &elt) const |
| { |
| return elt.*m_mptr == m_value; |
| } |
| }; |
| |
| template <typename T, typename V> |
| MemberPredicate<T, V> |
| predicate(V T::*m, V const &v) |
| { |
| return MemberPredicate<T, V>(m, v); |
| } |
| |
| template <typename Elt, ///< Element type. |
| typename Value ///< Member value type. |
| > |
| struct MethodPredicate { |
| typedef Value (Elt::*MethodPtr)() const; |
| Value const &m_value; ///< Value to test against. |
| MethodPtr m_mptr; ///< Pointer to method returning value. |
| MethodPredicate(MethodPtr mptr, Value const &v) : m_value(v), m_mptr(mptr) {} |
| bool |
| operator()(Elt const &elt) const |
| { |
| return (elt.*m_mptr)() == m_value; |
| } |
| }; |
| |
| template <typename T, typename V> |
| MethodPredicate<T, V> |
| predicate(V (T::*m)() const, V const &v) |
| { |
| return MethodPredicate<T, V>(m, v); |
| } |
| |
| } // namespace ts |