/* * InspIRCd -- Internet Relay Chat Daemon * * Copyright (C) 2026 Sadie Powell * * 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 . */ #pragma once namespace insp { template struct casemapped_equals_obj; template struct casemapped_hash_obj; template 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 using casemapped_flat_map = insp::flat_map>; /** A flat multimap where the key is a case insensitive string using the IRC casemapping. */ template using casemapped_flat_multimap = insp::flat_multimap>; /** A flat set where the key is a case insensitive string using the IRC casemapping. */ template using casemapped_flat_set = insp::flat_set>; /** A map where the key is a case insensitive string using the IRC casemapping. */ template using casemapped_map = std::map>; /** A flat multimap where the key is a case insensitive string using the IRC casemapping. */ template using casemapped_multimap = std::multimap>; /** An unordered map where the key is a case insensitive string using the IRC casemapping. */ template using casemapped_unordered_map = std::unordered_map, casemapped_equals_obj>; /** Determines if \p str1 and \p str2 are equivalent when compared case insensitively using the * specified 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, const casemap* map = nullptr); /** Determines if \p str1 is lexographically less than \p str2 when compared insensitively using * the specified 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, const casemap* map = nullptr); /** 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; namespace insp { /** Determines if \p str1 and \p str2 are equivalent when compared case insensitively using * ASCII 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. */ inline bool ascii_equals(const std::string_view& str1, const std::string_view& str2) { return casemapped_equals(str1, str2, ascii_case_insensitive_map); } /** Determines if \p str1 is lexographically less than \p str2 when compared insensitively using * ASCII 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. */ inline bool ascii_less(const std::string_view& str1, const std::string_view& str2) { return casemapped_less(str1, str2, ascii_case_insensitive_map); } } /** IRC casemapping variant of \p std::equal_to. */ template 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. */ template 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. */ template 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); } };