diff --git a/mediapipe/framework/deps/BUILD b/mediapipe/framework/deps/BUILD index 7994aae75..7fe37bae6 100644 --- a/mediapipe/framework/deps/BUILD +++ b/mediapipe/framework/deps/BUILD @@ -305,6 +305,14 @@ cc_library( ], ) +cc_library( + name = "requires", + hdrs = ["requires.h"], + + # Use this library through "mediapipe/framework/port:requires". + visibility = ["//mediapipe/framework/port:__pkg__"], +) + cc_library( name = "ret_check", srcs = ["ret_check.cc"], diff --git a/mediapipe/framework/deps/requires.h b/mediapipe/framework/deps/requires.h new file mode 100644 index 000000000..576aa34bb --- /dev/null +++ b/mediapipe/framework/deps/requires.h @@ -0,0 +1,61 @@ +// Copyright 2023 The MediaPipe Authors. +// +// 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 MEDIAPIPE_DEPS_REQUIRES_H_ +#define MEDIAPIPE_DEPS_REQUIRES_H_ + +#include + +namespace mediapipe { + +// C++17 port of the C++20 `requires` expressions. +// It allows easy inline test of properties of types in template code. +// https://en.cppreference.com/w/cpp/language/constraints#Requires_expressions +// +// Example usage: +// +// if constexpr (Requires([](auto&& x) -> decltype(x.foo()) {})) { +// // T has foo() +// return t.foo(); +// } else if constexpr (Requires([](auto&& x) -> decltype(Bar(x)) {})) { +// // Can call Bar with T +// return Bar(t); +// } else if constexpr (Requires( +// // Can test expression with multiple inputs +// [](auto&& x, auto&& y) -> decltype(x + y) {})) { +// return t + t2; +// } +// +// The `Requires` function takes a list of types and a generic lambda where all +// arguments are of type `auto&&`. The lambda is never actually invoked and the +// body must be empty. +// When used this way, `Requires` returns whether the expression inside +// `decltype` is well-formed, when the lambda parameters have the types that +// are specified by the corresponding template arguments. +// +// NOTE: C++17 does not allow lambdas in template parameters, which means that +// code like the following is _not_ valid in C++17: +// +// template ( +// [] (auto&& v) -> decltype() {})>> +// +template +constexpr bool Requires(F) { + return std::is_invocable_v; +} + +} // namespace mediapipe + +#endif // MEDIAPIPE_DEPS_REQUIRES_H_ diff --git a/mediapipe/framework/port/BUILD b/mediapipe/framework/port/BUILD index 5b0a0feca..cae439bc0 100644 --- a/mediapipe/framework/port/BUILD +++ b/mediapipe/framework/port/BUILD @@ -445,3 +445,9 @@ cc_library( hdrs = ["vector.h"], deps = ["//mediapipe/framework/deps:vector"], ) + +cc_library( + name = "requires", + hdrs = ["requires.h"], + deps = ["//mediapipe/framework/deps:requires"], +) diff --git a/mediapipe/framework/port/requires.h b/mediapipe/framework/port/requires.h new file mode 100644 index 000000000..eab622b22 --- /dev/null +++ b/mediapipe/framework/port/requires.h @@ -0,0 +1,20 @@ +// Copyright 2023 The MediaPipe Authors. +// +// 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 MEDIAPIPE_FRAMEWORK_PORT_REQUIRES_H_ +#define MEDIAPIPE_FRAMEWORK_PORT_REQUIRES_H_ + +#include "mediapipe/framework/deps/requires.h" + +#endif // MEDIAPIPE_FRAMEWORK_PORT_REQUIRES_H_