Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
collide.h
Go to the documentation of this file.
1
12
13/*
14Copyright (c) 2026 MrXie1109
15
16Permission is hereby granted, free of charge, to any person obtaining a copy
17of this software and associated documentation files (the "Software"), to deal
18in the Software without restriction, including without limitation the rights
19to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20copies of the Software, and to permit persons to whom the Software is
21furnished to do so, subject to the following conditions:
22
23The above copyright notice and this permission notice shall be included in all
24copies or substantial portions of the Software.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32SOFTWARE.
33*/
34
35#pragma once
36#include <functional>
37#include <memory>
38#include <string>
39#include <typeindex>
40#include <unordered_map>
41#include <utility>
42
43#include "../core/csexc.h"
44#ifdef __GNUG__
45#include <cxxabi.h>
46#endif
47
48namespace console {
55 struct PairHash {
63 template <typename T1, typename T2>
64 std::size_t operator()(std::pair<T1, T2> p) const {
65 auto h1 = std::hash<T1>{}(p.first);
66 auto h2 = std::hash<T2>{}(p.second);
67 return h1 ^ (h2 << 1);
68 }
69 };
70
101 template <class T, class F = std::function<void(T &, T &)>>
102 class Table {
103 public:
105 typedef std::pair<std::type_index, std::type_index> KeyType;
107 typedef F FunctionType;
108
116
124 void add(const std::type_index &type1,
125 const std::type_index &type2,
126 FunctionType func) {
127 table[{type1, type2}] = func;
128 }
129
138 void add_symmetric(const std::type_info &type1,
139 const std::type_info &type2,
140 FunctionType func) {
141 add(type1, type2, func);
142 add(type2, type1, func);
143 }
144
153 const std::type_index &type1, const std::type_index &type2) const {
154 auto it = table.find({type1, type2});
155 if (it != table.end())
156 return it->second;
157 else if (default_handler)
158 return default_handler;
159 else {
160 static auto get_name
161 = [](const std::type_index &ti) -> std::string {
162#ifdef _MSC_VER
163 return ti.name();
164#elif defined(__GNUG__)
165 int status = 0;
166 std::unique_ptr<char, void (*)(void *)> result(
167 abi::__cxa_demangle(
168 ti.name(), nullptr, nullptr, &status),
169 std::free);
170 return (status == 0) ? result.get() : ti.name();
171#else
172 return ti.name();
173#endif
174 };
175 throw TypeError("Bad Collide Type: <" + get_name(type1)
176 + "> & <" + get_name(type2) + ">");
177 }
178 }
179
187 void call(T &a, T &b) const { (*this)(typeid(a), typeid(b))(a, b); }
188
195 bool
196 has(const std::type_index &type1, const std::type_index &type2) const {
197 return table.find({type1, type2}) != table.end();
198 }
199
204 bool has_default() const { return static_cast<bool>(default_handler); }
205
214 const std::type_index &type1, const std::type_index &type2) const {
215 return has(type1, type2) || static_cast<bool>(default_handler);
216 }
217
223 default_handler = func;
224 }
225
231 void
232 remove(const std::type_index &type1, const std::type_index &type2) {
233 table.erase({type1, type2});
234 }
235
241 void clear() { table.clear(); }
242
243 private:
248 std::unordered_map<KeyType, FunctionType, PairHash> table;
249
254 };
255}
bool has_default() const
检查是否设置了默认处理函数。
Definition collide.h:204
FunctionType default_handler
默认处理函数。
Definition collide.h:253
void clear()
清空所有注册的类型对和处理函数。
Definition collide.h:241
void add_symmetric(const std::type_info &type1, const std::type_info &type2, FunctionType func)
对称地注册一个类型对的处理函数。
Definition collide.h:138
F FunctionType
存储的函数类型。
Definition collide.h:107
bool has(const std::type_index &type1, const std::type_index &type2) const
检查是否为特定的类型对注册了处理函数。
Definition collide.h:196
void add(const std::type_index &type1, const std::type_index &type2, FunctionType func)
注册一个类型对的处理函数(非对称)。
Definition collide.h:124
void call(T &a, T &b) const
根据两个对象的运行时类型调用对应的处理函数。
Definition collide.h:187
Table(FunctionType default_handler=FunctionType{})
构造 Table。
Definition collide.h:114
std::unordered_map< KeyType, FunctionType, PairHash > table
存储类型对到函数的映射。
Definition collide.h:248
bool callable(const std::type_index &type1, const std::type_index &type2) const
检查是否为特定的类型对注册了处理函数,或者是否设置了默认处理函数。
Definition collide.h:213
void set_default(FunctionType func=FunctionType{})
设置默认处理函数,当没有找到特定类型对的函数时调用。
Definition collide.h:222
FunctionType operator()(const std::type_index &type1, const std::type_index &type2) const
根据两个类型获取对应的处理函数。
Definition collide.h:152
std::pair< std::type_index, std::type_index > KeyType
用作映射键的类型:type_index 对。
Definition collide.h:105
void remove(const std::type_index &type1, const std::type_index &type2)
移除一个类型对的处理函数。
Definition collide.h:232
TypeError(const std::string &msg)
构造 TypeError。
Definition csexc.h:102
定义 console 库使用的自定义异常类层次结构。
本库所有组件所在的顶层命名空间。
用于 std::pair 类型的哈希函数对象。
Definition collide.h:55
std::size_t operator()(std::pair< T1, T2 > p) const
计算一对值的哈希值。
Definition collide.h:64