aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-21 15:37:09 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-21 15:37:09 +0800
commit98b8218afdb00497a0d4373a6023e04686d1e559 (patch)
treeee628af5425b49b15c1a2e40d16c11dabe8d0a43
parentd3600551e313a40e822970b56b9fc71ba6c9edcc (diff)
downloadrcc-project-98b8218afdb00497a0d4373a6023e04686d1e559.tar.gz
rcc-project-98b8218afdb00497a0d4373a6023e04686d1e559.tar.xz
[ADT] Add function_ref to ADT
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
-rw-r--r--rcc/include/rcc/ADT/STLFunctionalExtras.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/rcc/include/rcc/ADT/STLFunctionalExtras.h b/rcc/include/rcc/ADT/STLFunctionalExtras.h
new file mode 100644
index 0000000..71a5b85
--- /dev/null
+++ b/rcc/include/rcc/ADT/STLFunctionalExtras.h
@@ -0,0 +1,112 @@
+/*
+ R *CC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option) any
+ later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ RCC-Project; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>.
+ */
+
+//===- llvm/ADT/STLFunctionalExtras.h - Extras for <functional> -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some extension to <functional>.
+//
+// No library is required when using these functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef RCC_ADT_STLFUNCTIONALEXTRAS_H
+#define RCC_ADT_STLFUNCTIONALEXTRAS_H
+
+#include "rcc/Support/Compiler.h"
+
+#include <cstddef
+#include <cstdint>
+#include <type_traits>
+#include <utility>
+
+namespace rcc
+{
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+/// An efficient, type-erasing, non-owning reference to a callable. This is
+/// intended for use as the type of a function parameter that is not used
+/// after the function in question returns.
+///
+/// This class does not own the callable, so it is not in general safe to store
+/// a function_ref.
+template <typename Fn> class function_ref;
+
+template <typename Ret, typename... Params>
+class RCC_GSL_POINTER function_ref<Ret (Params...)>
+{
+ Ret (*callback) (intptr_t callable, Params... params) = nullptr;
+ intptr_t callable = 0;
+
+ template <typename Callable>
+ static Ret
+ callback_fn (intptr_t callable, Params... params)
+ {
+ return (*reinterpret_cast<Callable *> (callable)) (
+ std::forward<Params> (params)...);
+ }
+
+public:
+ function_ref () = default;
+ function_ref (std::nullptr_t)
+ {
+ }
+
+ template <typename Callable>
+ function_ref (
+ Callable &&callable RCC_LIFETIME_BOUND,
+ // This is not the copy-constructor.
+ std::enable_if_t<!std::is_same<std::remove_cvref_t<Callable>,
+ function_ref>::value> * = nullptr,
+ // Functor must be callable and return a suitable type.
+ std::enable_if_t<std::is_void<Ret>::value ||
+ std::is_convertible<decltype (std::declval<Callable> () (
+ std::declval<Params> ()...)),
+ Ret>::value> * = nullptr)
+ : callback (callback_fn<std::remove_reference_t<Callable>>),
+ callable (reinterpret_cast<intptr_t> (&callable))
+ {
+ }
+
+ Ret
+ operator() (Params... params) const
+ {
+ return callback (callable, std::forward<Params> (params)...);
+ }
+
+ explicit
+ operator bool () const
+ {
+ return callback;
+ }
+};
+
+} // end namespace rcc
+
+#endif // RCC_ADT_STLFUNCTIONALEXTRAS_H