aboutsummaryrefslogtreecommitdiff
path: root/include/casemap.h
blob: b31c7ed18912cb76bb1bdb400dc36f13940d935e (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * InspIRCd -- Internet Relay Chat Daemon
 *
 *   Copyright (C) 2026 Sadie Powell <sadie@witchery.services>
 *
 * This file is part of InspIRCd.  InspIRCd 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, version 2.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#pragma once

namespace insp
{
	template<typename, typename>
	struct casemapped_equals_obj;
	template<typename>
	struct casemapped_hash_obj;
	template<typename, typename>
	struct casemapped_less_obj;

	/** Holds a list of characters and the value they map to. */
	using casemap = unsigned char;

	/** A flat map where the key is a case insensitive string using the IRC casemapping. */
	template<typename Value, typename Key = std::string>
	using casemapped_flat_map = insp::flat_map<std::string, Value, casemapped_less_obj<Key, Key>>;

	/** A flat multimap where the key is a case insensitive string using the IRC casemapping. */
	template<typename Value, typename Key = std::string>
	using casemapped_flat_multimap = insp::flat_multimap<std::string, Value, casemapped_less_obj<Key, Key>>;

	/** A flat set where the key is a case insensitive string using the IRC casemapping. */
	template<typename Key = std::string>
	using casemapped_flat_set = insp::flat_set<Key, casemapped_less_obj<Key, Key>>;

	/** A map where the key is a case insensitive string using the IRC casemapping. */
	template<typename Value, typename Key = std::string>
	using casemapped_map = std::map<Key, Value, casemapped_less_obj<Key, Key>>;

	/** A flat multimap where the key is a case insensitive string using the IRC casemapping. */
	template<typename Value, typename Key = std::string>
	using casemapped_multimap = std::multimap<Key, Value, casemapped_less_obj<Key, Key>>;

	/** An unordered map where the key is a case insensitive string using the IRC casemapping. */
	template<typename Value, typename Key = std::string>
	using casemapped_unordered_map = std::unordered_map<Key, Value, casemapped_hash_obj<Key>, casemapped_equals_obj<Key, Key>>;

	/** Determines if \p str1 and \p str2 are equivalent when compared case insensitively using the
	 * configured IRC casemapping.
	 * @param str1 The first string to compare.
	 * @param str2 The second string to compare.
	 * @return True if \p str1 and \p str2 are equivalent; otherwise, false.
	 */
	CoreExport bool casemapped_equals(const std::string_view& str1, const std::string_view& str2);

	/** Determines if \p str1 is lexographically less than \p str2 when compared insensitively using
	 * the configured IRC casemapping.
	 * @param str1 The first string to compare.
	 * @param str2 The second string to compare.
	 * @return True if \p str1 is ranked lower than \p str2; otherwise, false.
	 */
	CoreExport bool casemapped_less(const std::string_view& str1, const std::string_view& str2);

	/** Determines the unique hash of \p str for use in a hash map when hashed insensitively using
	 * the configured IRC casemapping.
	 * @param str The string to hash.
	 * @return The unique hash of \p str.
	 */
	CoreExport size_t casemapped_hash(const std::string_view& str);
}

/** A casemapping that uses ASCII rules, i.e. A-Z are mapped to a-z. */
extern CoreExport const insp::casemap ascii_case_insensitive_map[256];

/** The currently configured casemapping. This defaults to \ref ascii_case_insensitive_map. */
extern CoreExport const insp::casemap* national_case_insensitive_map;

/** IRC casemapping variant of \p std::equal_to<String>. */
template<typename String1, typename String2>
struct insp::casemapped_equals_obj
{
	/** @copydoc insp::casemapped_equals */
	inline bool operator()(const String1& str1, const String2& str2) const
	{
		return insp::casemapped_equals(str1, str2);
	}
};

/** IRC casemapping variant of std::hash<String>. */
template<typename String>
struct insp::casemapped_hash_obj
{
	/** @copydoc insp::casemapped_hash */
	inline size_t operator()(const String& str) const
	{
		return insp::casemapped_hash(str);
	}
};

/** IRC casemapping variant of std::less<String>. */
template<typename String1, typename String2>
struct insp::casemapped_less_obj
{
	/** @copydoc insp::casemapped_less */
	inline bool operator()(const String1& str1, const String2& str2) const
	{
		return insp::casemapped_less(str1, str2);
	}
};