Program Listing for File policy.hpp
↰ Return to documentation for file (include/beluga/policies/policy.hpp
)
// Copyright 2024 Ekumen, Inc.
//
// Licensed 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.
#ifndef BELUGA_POLICIES_POLICY_HPP
#define BELUGA_POLICIES_POLICY_HPP
#include <type_traits>
namespace beluga {
template <class PolicyFn>
struct policy;
namespace detail {
struct make_policy_fn {
template <class Fn>
constexpr policy<Fn> operator()(Fn&& fn) const {
return policy<Fn>{std::forward<Fn>(fn)};
}
};
} // namespace detail
inline constexpr detail::make_policy_fn make_policy;
struct policy_base {
template <class Left, class Right>
friend constexpr auto operator&&(policy<Left> left, policy<Right> right) {
return make_policy([=](const auto&... args) mutable -> bool { return left(args...) && right(args...); });
}
template <class Left, class Right>
friend constexpr auto operator&(policy<Left> left, policy<Right> right) {
return make_policy([=](const auto&... args) mutable -> bool {
const bool first = left(args...);
const bool second = right(args...);
return first && second;
});
}
template <class Left, class Right>
friend constexpr auto operator||(policy<Left> left, policy<Right> right) {
return make_policy([=](const auto&... args) mutable -> bool { return left(args...) || right(args...); });
}
template <class Left, class Right>
friend constexpr auto operator|(policy<Left> left, policy<Right> right) {
return make_policy([=](const auto&... args) mutable -> bool {
const bool first = left(args...);
const bool second = right(args...);
return first || second;
});
}
template <class Fn>
friend constexpr auto operator!(policy<Fn> fn) {
return make_policy([=](const auto&... args) mutable -> bool { return !fn(args...); });
}
};
template <class PolicyFn>
struct policy : public policy_base, public PolicyFn {
policy() = default;
constexpr explicit policy(PolicyFn fn) : PolicyFn(std::move(fn)) {}
using PolicyFn::PolicyFn;
using PolicyFn::operator=;
using PolicyFn::operator();
template <class... Args>
constexpr auto operator()(Args...) -> //
std::enable_if_t< //
std::is_invocable_r_v<bool, PolicyFn> && !std::is_invocable_r_v<bool, PolicyFn, Args...>,
bool> {
return (*this)();
}
};
template <class... Args>
using any_policy = policy<std::function<bool(Args...)>>;
} // namespace beluga
#endif