aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/types/AnyRef.hpp
diff options
context:
space:
mode:
author Spartan322 <Megacake1234@gmail.com>2023-12-20 00:45:09 +0100
committer Spartan322 <Megacake1234@gmail.com>2024-01-03 01:46:54 +0100
commit5fa456c21ad950a6f269b83f5e88ce8c90ae9a14 (patch)
treef8f1b23dd13a0f2029747404ad30ffa346b5e99f /src/openvic-simulation/types/AnyRef.hpp
parent66b80459c9d49895de902432bce11176b1270878 (diff)
Add diplomatic actions skeleton
Add AnyRef for cheap "move only" reference Add FunctionRef for cheap "move only" function reference Based on https://github.com/think-cell/think-cell-library/blob/main/tc/base/ref.h
Diffstat (limited to 'src/openvic-simulation/types/AnyRef.hpp')
-rw-r--r--src/openvic-simulation/types/AnyRef.hpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/openvic-simulation/types/AnyRef.hpp b/src/openvic-simulation/types/AnyRef.hpp
new file mode 100644
index 0000000..b50a039
--- /dev/null
+++ b/src/openvic-simulation/types/AnyRef.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <memory>
+
+namespace OpenVic {
+ // Based on https://github.com/think-cell/think-cell-library/blob/b9c84dd7fc926fad80829ed49705fa51afe36e87/tc/base/ref.h
+ // Boost Software License - Version 1.0 - August 17th, 2003
+
+ // Permission is hereby granted, free of charge, to any person or organization
+ // obtaining a copy of the software and accompanying documentation covered by
+ // this license (the "Software") to use, reproduce, display, distribute,
+ // execute, and transmit the Software, and to prepare derivative works of the
+ // Software, and to permit third-parties to whom the Software is furnished to
+ // do so, all subject to the following:
+
+ // The copyright notices in the Software and this entire statement, including
+ // the above license grant, this restriction and the following disclaimer,
+ // must be included in all copies of the Software, in whole or in part, and
+ // all derivative works of the Software, unless such copies or derivative
+ // works are solely in the form of machine-executable object code generated by
+ // a source language processor.
+
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ // DEALINGS IN THE SOFTWARE.
+ union AnyRef {
+ // Any pointer to function can be converted to a pointer to a different function type. Calling the
+ // function through a pointer to a different function type is undefined, but converting such pointer
+ // back to pointer to the original function type yields the pointer to the original function.
+ // https://en.cppreference.com/w/cpp/language/reinterpret_cast
+
+ template<typename T>
+ [[nodiscard]] static constexpr T* as_mutable_ptr(T const* pt) noexcept {
+ return const_cast<T*>(pt);
+ }
+
+ template<typename RefT>
+ explicit AnyRef(RefT& ref) noexcept : m_pvRef(std::addressof(ref)) {}
+
+ template<typename RefT>
+ requires std::is_function<RefT>::value
+ explicit AnyRef(RefT& ref) noexcept : m_fpvRef(reinterpret_cast<void (*)()>(std::addressof(ref))) {}
+
+ template<typename RefT> // may be const and/or volatile
+ RefT& get_ref() const& noexcept {
+ static_assert(!std::is_reference<RefT>::value);
+ if constexpr (std::is_function<RefT>::value) {
+ return *reinterpret_cast<RefT*>(m_fpvRef);
+ } else {
+ return *static_cast<RefT*>(as_mutable_ptr(m_pvRef));
+ }
+ }
+
+ void const* m_pvRef;
+ void (*m_fpvRef)();
+ };
+}