diff --git a/soh/soh/Enhancements/randomizer/archipelago.cpp b/soh/soh/Enhancements/randomizer/archipelago.cpp index 29be3b1f4..6953447e9 100644 --- a/soh/soh/Enhancements/randomizer/archipelago.cpp +++ b/soh/soh/Enhancements/randomizer/archipelago.cpp @@ -9,34 +9,10 @@ #include #include -#include "fixed_string.hpp" #include "randomizerTypes.h" #include "static_data.h" #include "../game-interactor/GameInteractor.h" -//extern "C" { -// #include "include/z64item.h" -// #include "objects/gameplay_keep/gameplay_keep.h" -// extern SaveContext gSaveContext; -// extern PlayState* gPlayState; -//} - -//constexpr const char* requestedSlotData(int i) - -using namespace fixstr; //https://github.com/unterumarmung/fixed_string -template -struct CallbackWrapper { - static void SlotCallbackFunc(int id) { - ArchipelagoClient::getInstance().add_slot_data(key, id); - SPDLOG_TRACE("Recieved Slot data ({}, {})", key, id); - } -}; - -template -auto SubscribeToSlotData() { - AP_RegisterSlotDataIntCallback(std::string(key), CallbackWrapper::SlotCallbackFunc); -} - ArchipelagoClient::ArchipelagoClient() { std::string uuid = ap_get_uuid("uuid"); @@ -57,110 +33,7 @@ ArchipelagoClient& ArchipelagoClient::getInstance() { return Client; } - -void ArchipelagoClient::add_slot_data(std::string_view key, int id) { - slot_data.insert(std::pair(key, id)); -} - -//void registerSlotCallbacks() { -// SubscribeToSlotData<"open_forest">(); -// SubscribeToSlotData<"open_kakoriko">(); -// SubscribeToSlotData<"open_door_of_time">(); -// SubscribeToSlotData<"zora_fountain">(); -// SubscribeToSlotData<"gerudo_fortress">(); -// SubscribeToSlotData<"bridge">(); -// SubscribeToSlotData<"bridge_stones">(); -// SubscribeToSlotData<"bridge_medallions">(); -// SubscribeToSlotData<"bridge_rewards">(); -// SubscribeToSlotData<"bridge_tokens">(); -//// SubscribeToSlotData<"bridge_hearts">(); -// SubscribeToSlotData<"shuffle_ganon_bosskey">(); -// SubscribeToSlotData<"ganon_bosskey_medallions">(); -// SubscribeToSlotData<"ganon_bosskey_stones">(); -// SubscribeToSlotData<"ganon_bosskey_rewards">(); -// SubscribeToSlotData<"ganon_bosskey_tokens">(); -//// SubscribeToSlotData<"ganon_bosskey_hearts">(); -// SubscribeToSlotData<"trials">(); -// SubscribeToSlotData<"triforce_hunt">(); -// SubscribeToSlotData<"triforce_goal">(); -//// SubscribeToSlotData<"extra_triforce_percentage">(); -//// SubscribeToSlotData<"shopsanity">(); -//// SubscribeToSlotData<"shop_slots">(); -// SubscribeToSlotData<"shopsanity_prices">(); -//// SubscribeToSlotData<"tokensanity">(); -//// SubscribeToSlotData<"dungeon_shortcuts">(); -//// SubscribeToSlotData<"mq_dungeons_mode">(); -//// SubscribeToSlotData<"mq_dungeons_count">(); -//// SubscribeToSlotData<"shuffle_interior_entrances">(); -//// SubscribeToSlotData<"shuffle_grotto_entrances">(); -//// SubscribeToSlotData<"shuffle_dungeon_entrances">(); -//// SubscribeToSlotData<"shuffle_overworld_entrances">(); -//// SubscribeToSlotData<"shuffle_bosses">(); -//// SubscribeToSlotData<"key_rings">(); -//// SubscribeToSlotData<"enhance_map_compass">(); -//// SubscribeToSlotData<"shuffle_mapcompass">(); -//// SubscribeToSlotData<"shuffle_smallkeys">(); -//// SubscribeToSlotData<"shuffle_hideoutkeys">(); -//// SubscribeToSlotData<"shuffle_bosskeys">(); -//// SubscribeToSlotData<"logic_rules">(); -//// SubscribeToSlotData<"logic_no_night_tokens_without_suns_song">(); -//// SubscribeToSlotData<"warp_songs">(); -//// SubscribeToSlotData<"shuffle_song_items">(); -//// SubscribeToSlotData<"shuffle_medigoron_carpet_salesman">(); -//// SubscribeToSlotData<"shuffle_frog_song_rupees">(); -//// SubscribeToSlotData<"shuffle_scrubs">(); -//// SubscribeToSlotData<"shuffle_child_trade">(); -//// SubscribeToSlotData<"shuffle_freestanding_items">(); -//// SubscribeToSlotData<"shuffle_pots">(); -//// SubscribeToSlotData<"shuffle_crates">(); -//// SubscribeToSlotData<"shuffle_cows">(); -//// SubscribeToSlotData<"shuffle_beehives">(); -//// SubscribeToSlotData<"shuffle_kokiri_sword">(); -//// SubscribeToSlotData<"shuffle_ocarinas">(); -//// SubscribeToSlotData<"shuffle_gerudo_card">(); -//// SubscribeToSlotData<"shuffle_beans">(); -// SubscribeToSlotData<"starting_age">(); -//// SubscribeToSlotData<"bombchus_in_logic">(); -//// SubscribeToSlotData<"spawn_positions">(); -//// SubscribeToSlotData<"owl_drops">(); -// SubscribeToSlotData<"no_epona_race">(); -//// SubscribeToSlotData<"skip_some_minigame_phases">(); -// SubscribeToSlotData<"complete_mask_quest">(); -// SubscribeToSlotData<"free_scarecrow">(); -//// SubscribeToSlotData<"plant_beans">(); -// SubscribeToSlotData<"chicken_count">(); -// SubscribeToSlotData<"big_poe_count">(); -//// SubscribeToSlotData<"fae_torch_count">(); -// SubscribeToSlotData<"blue_fire_arrows">(); -// SubscribeToSlotData<"damage_multiplier">(); -//// SubscribeToSlotData<"deadly_bonks">(); -//// SubscribeToSlotData<"starting_tod">(); -//// SubscribeToSlotData<"junk_ice_traps">(); -// SubscribeToSlotData<"start_with_consumables">(); -//// SubscribeToSlotData<"adult_trade_start">(); -//} - bool ArchipelagoClient::start_client() { - //switch(AP_GetConnectionStatus()) { - // case AP_ConnectionStatus::ConnectionRefused: - // SPDLOG_TRACE("refused"); - // break; - // case AP_ConnectionStatus::Authenticated: - // SPDLOG_TRACE("Authenticated"); - // break; - // case AP_ConnectionStatus::Connected: - // SPDLOG_TRACE("Connected"); - // break; - // case AP_ConnectionStatus::Disconnected: - // SPDLOG_TRACE("Disconnected"); - // break; - //} - - //if(AP_GetConnectionStatus() != AP_ConnectionStatus::Disconnected) { - // SPDLOG_TRACE("AP already connected, shutting it down"); - // AP_Shutdown(); - //} - if(apclient != NULL) { apclient.reset(); } @@ -203,13 +76,7 @@ bool ArchipelagoClient::start_client() { // todo implement me }); - //apclient.set_slot_connected_handler() // todo rewrite the old slot callbacks when i'm ready to read slot data again - //registerSlotCallbacks(); - //AP_Start(); - //AP_ConnectionStatus conn_status = AP_GetConnectionStatus(); - save_data(); - //return conn_status == AP_ConnectionStatus::Connected; return true; } @@ -236,7 +103,8 @@ bool ArchipelagoClient::isConnected() { } void ArchipelagoClient::check_location(RandomizerCheck SoH_check_id) { - std::string_view ap_name = Rando::StaticData::SohCheckToAP[SoH_check_id]; + //std::string_view ap_name = Rando::StaticData::SohCheckToAP[SoH_check_id]; + std::string ap_name = Rando::StaticData::GetLocation(SoH_check_id)->GetName(); if(ap_name.empty()) { return; } @@ -268,7 +136,7 @@ void ArchipelagoClient::on_connected() { void ArchipelagoClient::on_item_recieved(int64_t recieved_item_id, bool notify_player) { // call each callback - const std::string item_name = apclient->get_item_name(recieved_item_id, "Ocarina of Time"); + const std::string item_name = apclient->get_item_name(recieved_item_id, AP_Client_consts::AP_GAME_NAME); ArchipelagoClient& ap_client = ArchipelagoClient::getInstance(); if(ap_client.ItemRecievedCallback) { SPDLOG_TRACE("item recieved: {}, notify: {}", item_name, notify_player); diff --git a/soh/soh/Enhancements/randomizer/archipelago.h b/soh/soh/Enhancements/randomizer/archipelago.h index bda296a19..5106427e8 100644 --- a/soh/soh/Enhancements/randomizer/archipelago.h +++ b/soh/soh/Enhancements/randomizer/archipelago.h @@ -1,8 +1,6 @@ #pragma once #include "archipelago_settings_window.h" -#include "fixed_string.hpp" - #include "randomizerTypes.h" #include "static_data.h" #include @@ -20,7 +18,7 @@ namespace AP_Client_consts { static constexpr char const* SETTING_ADDRESS = "AP_server_address"; static constexpr char const* SETTING_NAME = "AP_slot_name"; - static constexpr char const* AP_GAME_NAME = "Ocarina of Time"; + static constexpr char const* AP_GAME_NAME = "Ocarina of Time (SoH)"; } class ArchipelagoClient{ @@ -49,10 +47,6 @@ class ArchipelagoClient{ const std::map& get_slot_data(); const std::vector& get_scouted_items(); - void add_slot_data(std::string_view key, int id); - - //void add_slot_data(std::string_view key, int id); - bool isConnected(); void check_location(RandomizerCheck SoH_check_id); @@ -90,18 +84,14 @@ class ArchipelagoClient{ std::map slot_data; std::set locations; std::vector scouted_items; - - //void registerSlotCallbacks(); void save_data(); // callback functions void on_connected(); - //void on_couldntConnect(AP_ConnectionStatus connection_status); void on_location_checked(int64_t location_id); void on_deathlink_recieved() { }; // TODO: implement me - //void on_location_scouted(const std::list& network_items); // callbacks std::function ItemRecievedCallback; diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index f38faa1c9..e875c7423 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -358,8 +358,9 @@ GetItemEntry Context::GetArchipelagoGIEntry() { } // get the first item from the archipelago queue - std::string_view recieved_ap_item = mAPrecieveQueue.front(); - RandomizerGet item_id = StaticData::APitemToSoh[recieved_ap_item]; + std::string recieved_ap_item = mAPrecieveQueue.front(); + RandomizerGet item_id = StaticData::itemNameToEnum[recieved_ap_item]; + //RandomizerGet item_id = StaticData::APitemToSoh[recieved_ap_item]; assert(item_id != RG_NONE); Item& item = StaticData::RetrieveItem(item_id); @@ -491,12 +492,14 @@ void Context::ParseArchipelagoItemsLocations(const std::vectorsecond; + //const RandomizerCheck rc = StaticData::APcheckToSoh.find(ap_item.locationName)->second; + const RandomizerCheck rc = StaticData::locationNameToEnum[ap_item.locationName]; if(SlotName == ap_item.playerName) { // our item SPDLOG_TRACE("Populated item {} at location {}", ap_item.itemName, ap_item.locationName); - const RandomizerGet item = StaticData::APitemToSoh.find(ap_item.itemName)->second; + const RandomizerGet item = StaticData::itemNameToEnum[ap_item.itemName]; + //const RandomizerGet item = StaticData::APitemToSoh.find(ap_item.itemName)->second; itemLocationTable[rc].SetPlacedItem(item); } else { // other player item diff --git a/soh/soh/Enhancements/randomizer/fixed_string.hpp b/soh/soh/Enhancements/randomizer/fixed_string.hpp deleted file mode 100644 index 92876e5c1..000000000 --- a/soh/soh/Enhancements/randomizer/fixed_string.hpp +++ /dev/null @@ -1,682 +0,0 @@ -/* - Licensed under the MIT License . - SPDX-License-Identifier: MIT - Copyright (c) 2020 - 2020 Daniil Dudkin. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -#ifndef FIXED_STRING_HPP -#define FIXED_STRING_HPP - -#include -#include -#include -#include -#include -#include - -#define FIXSTR_VERSION_MAJOR 0 -#define FIXSTR_VERSION_MINOR 1 -#define FIXSTR_VERSION_PATCH 1 - -#define FIXSTR_CPP20_CHAR8T_PRESENT __cpp_char8_t -#define FIXSTR_CPP20_SPACESHIP_OPERATOR_PRESENT __cpp_lib_three_way_comparison - -#define FIXSTR_CPP20_CONSTEXPR_ALGORITHMS_PRESENT (__cpp_lib_constexpr_algorithms) - -#ifdef _MSC_VER -#define FIXSTR_CPP_VERSION _MSVC_LANG -#else -#define FIXSTR_CPP_VERSION __cplusplus -#endif // _MSC_VER - -// Note that when ICC or Clang is in use, FIXSTR_GCC_VERSION might not fully match the actual GCC version on the system. -#define FIXSTR_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -// According to clang documentation, version can be vendor specific -#define FIXSTR_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) - -#if FIXSTR_GCC_VERSION >= 100'000 && FIXSTR_CPP_VERSION > 201703L -#define FIXSTR_CPP20_CNTTP_PRESENT 1 -#elif __cpp_nontype_template_args >= 201911 -#define FIXSTR_CPP20_CNTTP_PRESENT 1 -#elif __cpp_nontype_template_parameter_class >= 201806 -#define FIXSTR_CPP20_CNTTP_PRESENT 1 -#else -// Other compilers do not support cNTTP just yet -#define FIXSTR_CPP20_CNTTP_PRESENT 0 -#endif // FIXSTR_CPP20_CNTTP_PRESENT - -namespace fixstr -{ - -namespace details -{ -template -constexpr OutputIterator copy(InputIterator first, InputIterator last, OutputIterator d_first) -{ -#if FIXSTR_CPP20_CONSTEXPR_ALGORITHMS_PRESENT - return std::copy(first, last, d_first); -#else - while (first != last) - { - *d_first++ = *first++; - } - return d_first; -#endif // FIXSTR_CPP20_CONSTEXPR_ALGORITHMS_PRESENT -} - -template -constexpr void fill(ForwardIterator first, ForwardIterator last, const T& value) -{ -#if FIXSTR_CPP20_CONSTEXPR_ALGORITHMS_PRESENT - std::fill(first, last, value); -#else - for (; first != last; ++first) - { - *first = value; - } -#endif // FIXSTR_CPP20_CONSTEXPR_ALGORITHMS_PRESENT -} - -} // namespace details - -template > -struct basic_fixed_string // NOLINT(cppcoreguidelines-special-member-functions) -{ - // exposition only - using storage_type = std::array; - storage_type _data{}; - - using traits_type = TTraits; - using value_type = TChar; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = value_type&; - using const_reference = const value_type&; - using iterator = typename storage_type::iterator; - using const_iterator = typename storage_type::const_iterator; - using reverse_iterator = typename storage_type::reverse_iterator; - using const_reverse_iterator = typename storage_type::const_reverse_iterator; - using size_type = size_t; - using difference_type = ptrdiff_t; - using string_view_type = std::basic_string_view; - static constexpr auto npos = string_view_type::npos; - - constexpr basic_fixed_string() noexcept = default; - - constexpr basic_fixed_string(const value_type (&array)[N + 1]) noexcept // NOLINT(google-explicit-constructor) - { - details::copy(std::begin(array), std::end(array), _data.begin()); - } - - constexpr basic_fixed_string& operator=(const value_type (&array)[N + 1]) noexcept - { - details::copy(std::begin(array), std::end(array), _data.begin()); - return *this; - } - - // iterators - [[nodiscard]] constexpr iterator begin() noexcept { return _data.begin(); } - [[nodiscard]] constexpr const_iterator begin() const noexcept { return _data.begin(); } - [[nodiscard]] constexpr iterator end() noexcept { return _data.end() - 1; } - [[nodiscard]] constexpr const_iterator end() const noexcept { return _data.end() - 1; } - [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return _data.cbegin(); } - [[nodiscard]] constexpr const_iterator cend() const noexcept { return _data.cend() - 1; } - [[nodiscard]] constexpr reverse_iterator rbegin() noexcept { return _data.rbegin() + 1; } - [[nodiscard]] constexpr const_reverse_iterator rbegin() const noexcept { return _data.rbegin() + 1; } - [[nodiscard]] constexpr reverse_iterator rend() noexcept { return _data.rend(); } - [[nodiscard]] constexpr const_reverse_iterator rend() const noexcept { return _data.rend(); } - [[nodiscard]] constexpr const_reverse_iterator crbegin() const noexcept { return _data.crbegin() + 1; } - [[nodiscard]] constexpr const_reverse_iterator crend() const noexcept { return _data.crend(); } - - private: - [[nodiscard]] constexpr static bool static_empty() noexcept { return N == 0; } - - public: - // capacity - [[nodiscard]] constexpr size_type size() const noexcept { return N; } - [[nodiscard]] constexpr size_type length() const noexcept { return N; } - [[nodiscard]] constexpr size_type max_size() const noexcept { return N; } - [[nodiscard]] constexpr bool empty() const noexcept { return static_empty(); } - - // element access - [[nodiscard]] constexpr reference operator[](size_type n) { return _data[n]; } - [[nodiscard]] constexpr const_reference operator[](size_type n) const { return _data[n]; } - [[nodiscard]] constexpr reference at(size_type n) { return _data.at(n); } - [[nodiscard]] constexpr const_reference at(size_type n) const { return _data.at(n); } - - // The lack of C++20 concepts is disappointing - // Basically what every `template<...>` line means is `requires (!empty())` - template > - [[nodiscard]] constexpr reference front() noexcept - { - return _data.front(); - } - template > - [[nodiscard]] constexpr const_reference front() const noexcept - { - return _data.front(); - } - template > - [[nodiscard]] constexpr reference back() noexcept - { - return _data[size() - 1]; - } - template > - [[nodiscard]] constexpr const_reference back() const noexcept - { - return _data[size() - 1]; - } - - [[nodiscard]] constexpr pointer data() noexcept { return _data.data(); } - [[nodiscard]] constexpr const_pointer data() const noexcept { return _data.data(); } - - [[nodiscard]] constexpr const_pointer c_str() const noexcept { return data(); } - - private: - template - using same_with_other_size = basic_fixed_string; - - template - constexpr static size_type calculate_substr_size() - { - if constexpr (pos >= size) - return 0; - - constexpr size_type rcount = std::min(count, size - pos); - - return rcount; - } - - template - using substr_result_type = same_with_other_size()>; - - public: - // string operations - [[nodiscard]] constexpr operator string_view_type() const noexcept // NOLINT(google-explicit-constructor) - { - return {data(), N}; - } - - // clang-format off - template > - [[nodiscard]] constexpr auto substr() const noexcept - -> substr_result_type - // clang-format on - { - substr_result_type result; - details::copy(begin() + pos, begin() + pos + result.size(), result.begin()); - return result; - } - - template - [[nodiscard]] constexpr size_type find(const same_with_other_size& str, size_type pos = 0) const noexcept - { - if constexpr (M > N) - return npos; - return sv().find(str.sv(), pos); - } - [[nodiscard]] constexpr size_type find(string_view_type sv, size_type pos = 0) const noexcept { return sv().find(sv, pos); } - [[nodiscard]] constexpr size_type find(const value_type* s, size_type pos, size_type n) const { return sv().find(s, pos, n); } - [[nodiscard]] constexpr size_type find(const value_type* s, size_type pos = 0) const { return sv().find(s, pos); } - [[nodiscard]] constexpr size_type find(value_type c, size_type pos = 0) const noexcept { return sv().find(c, pos); } - - template - [[nodiscard]] constexpr size_type rfind(const same_with_other_size& str, size_type pos = npos) const noexcept - { - if constexpr (M > N) - return npos; - return sv().rfind(str.sv(), pos); - } - [[nodiscard]] constexpr size_type rfind(string_view_type sv, size_type pos = npos) const noexcept { return sv().rfind(sv, pos); } - [[nodiscard]] constexpr size_type rfind(const value_type* s, size_type pos, size_type n) const { return sv().rfind(s, pos, n); } - [[nodiscard]] constexpr size_type rfind(const value_type* s, size_type pos = npos) const { return sv().rfind(s, pos); } - [[nodiscard]] constexpr size_type rfind(value_type c, size_type pos = npos) const noexcept { return sv().rfind(c, pos); } - - template - [[nodiscard]] constexpr size_type find_first_of(const same_with_other_size& str, size_type pos = 0) const noexcept - { - if constexpr (M > N) - return npos; - return sv().find_first_of(str.sv(), pos); - } - [[nodiscard]] constexpr size_type find_first_of(string_view_type sv, size_type pos = 0) const noexcept { return sv().find_first_of(sv, pos); } - [[nodiscard]] constexpr size_type find_first_of(const value_type* s, size_type pos, size_type n) const { return sv().find_first_of(s, pos, n); } - [[nodiscard]] constexpr size_type find_first_of(const value_type* s, size_type pos = 0) const { return sv().find_first_of(s, pos); } - [[nodiscard]] constexpr size_type find_first_of(value_type c, size_type pos = 0) const noexcept { return sv().find_first_of(c, pos); } - - template - [[nodiscard]] constexpr size_type find_last_of(const same_with_other_size& str, size_type pos = npos) const noexcept - { - if constexpr (M > N) - return npos; - return sv().find_last_of(str.sv(), pos); - } - [[nodiscard]] constexpr size_type find_last_of(string_view_type sv, size_type pos = npos) const noexcept { return sv().find_last_of(sv, pos); } - [[nodiscard]] constexpr size_type find_last_of(const value_type* s, size_type pos, size_type n) const { return sv().find_last_of(s, pos, n); } - [[nodiscard]] constexpr size_type find_last_of(const value_type* s, size_type pos = npos) const { return sv().find_last_of(s, pos); } - [[nodiscard]] constexpr size_type find_last_of(value_type c, size_type pos = npos) const noexcept { return sv().find_last_of(c, pos); } - - template - [[nodiscard]] constexpr size_type find_first_not_of(const same_with_other_size& str, size_type pos = 0) const noexcept - { - if constexpr (M > N) - return npos; - return sv().find_first_of(str.sv(), pos); - } - [[nodiscard]] constexpr size_type find_first_not_of(string_view_type sv, size_type pos = 0) const noexcept { return sv().find_first_not_of(sv, pos); } - [[nodiscard]] constexpr size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const { return sv().find_first_not_of(s, pos, n); } - [[nodiscard]] constexpr size_type find_first_not_of(const value_type* s, size_type pos = 0) const { return sv().find_first_not_of(s, pos); } - [[nodiscard]] constexpr size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept { return sv().find_first_not_of(c, pos); } - - template - [[nodiscard]] constexpr size_type find_last_not_of(const same_with_other_size& str, size_type pos = npos) const noexcept - { - if constexpr (M > N) - return npos; - return sv().find_last_of(str.sv(), pos); - } - [[nodiscard]] constexpr size_type find_last_not_of(string_view_type sv, size_type pos = npos) const noexcept { return sv().find_last_not_of(sv, pos); } - [[nodiscard]] constexpr size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const { return sv().find_last_not_of(s, pos, n); } - [[nodiscard]] constexpr size_type find_last_not_of(const value_type* s, size_type pos = npos) const { return sv().find_last_not_of(s, pos); } - [[nodiscard]] constexpr size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept { return sv().find_last_not_of(c, pos); } - - [[nodiscard]] constexpr int compare(string_view_type v) const noexcept { return sv().compare(v); } - [[nodiscard]] constexpr int compare(size_type pos1, size_type count1, string_view_type v) const { return sv().compare(pos1, count1, v); } - [[nodiscard]] constexpr int compare(size_type pos1, size_type count1, string_view_type v, size_type pos2, size_type count2) const - { - return sv().compare(pos1, count1, v, pos2, count2); - } - [[nodiscard]] constexpr int compare(const value_type* s) const { return sv().compare(s); } - [[nodiscard]] constexpr int compare(size_type pos1, size_type count1, const value_type* s) const { return sv().compare(pos1, count1, s); } - [[nodiscard]] constexpr int compare(size_type pos1, size_type count1, const value_type* s, size_type count2) const - { - return sv().compare(pos1, count1, s, count2); - } - - [[nodiscard]] constexpr bool starts_with(string_view_type v) const noexcept { return sv().substr(0, v.size()) == v; } - [[nodiscard]] constexpr bool starts_with(char c) const noexcept { return !empty() && traits_type::eq(front(), c); } - [[nodiscard]] constexpr bool starts_with(const value_type* s) const noexcept { return starts_with(string_view_type(s)); } - - [[nodiscard]] constexpr bool ends_with(string_view_type sv) const noexcept { return size() >= sv.size() && compare(size() - sv.size(), npos, sv) == 0; } - [[nodiscard]] constexpr bool ends_with(value_type c) const noexcept { return !empty() && traits_type::eq(back(), c); } - [[nodiscard]] constexpr bool ends_with(const value_type* s) const { return ends_with(string_view_type(s)); } - - [[nodiscard]] constexpr bool contains(string_view_type sv) const noexcept { return find(sv) != npos; } - [[nodiscard]] constexpr bool contains(value_type c) const noexcept { return find(c) != npos; } - [[nodiscard]] constexpr bool contains(const value_type* s) const { return find(s) != npos; } - - void swap(basic_fixed_string& other) noexcept(std::is_nothrow_swappable_v) { _data.swap(other._data); } - - private: - constexpr string_view_type sv() const { return *this; } -}; - -template -void swap(basic_fixed_string& lhs, basic_fixed_string& rhs) noexcept(noexcept(lhs.swap(rhs))) -{ - lhs.swap(rhs); -} - -template -[[nodiscard]] constexpr bool operator==(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - if constexpr (M1 != M2) - return false; - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) == rhs; -} - -template -[[nodiscard]] constexpr bool operator==(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) == rhs; -} - -template -[[nodiscard]] constexpr bool operator==(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs == static_cast(rhs); -} - -#if FIXSTR_CPP20_SPACESHIP_OPERATOR_PRESENT - -template -[[nodiscard]] constexpr auto operator<=>(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) <=> rhs; -} - -template -[[nodiscard]] constexpr auto operator<=>(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) <=> rhs; -} - -template -[[nodiscard]] constexpr auto operator<=>(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs <=> static_cast(rhs); -} - -#else - -template -[[nodiscard]] constexpr bool operator!=(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - if constexpr (M1 != M2) - return true; - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) != rhs; -} - -template -[[nodiscard]] constexpr bool operator!=(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) != rhs; -} - -template -[[nodiscard]] constexpr bool operator!=(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs != static_cast(rhs); -} - -template -[[nodiscard]] constexpr bool operator<(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) < rhs; -} - -template -[[nodiscard]] constexpr bool operator<(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) < rhs; -} - -template -[[nodiscard]] constexpr bool operator<(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs < static_cast(rhs); -} - -template -[[nodiscard]] constexpr bool operator<=(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) <= rhs; -} - -template -[[nodiscard]] constexpr bool operator<=(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) <= rhs; -} - -template -[[nodiscard]] constexpr bool operator<=(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs <= static_cast(rhs); -} - -template -[[nodiscard]] constexpr bool operator>(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) > rhs; -} - -template -[[nodiscard]] constexpr bool operator>(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) > rhs; -} - -template -[[nodiscard]] constexpr bool operator>(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs > static_cast(rhs); -} - -template -[[nodiscard]] constexpr bool operator>=(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) >= rhs; -} - -template -[[nodiscard]] constexpr bool operator>=(const basic_fixed_string& lhs, std::basic_string_view rhs) -{ - using lhs_type = std::decay_t; - using sv_type = typename lhs_type::string_view_type; - return static_cast(lhs) >= rhs; -} - -template -[[nodiscard]] constexpr bool operator>=(std::basic_string_view lhs, const basic_fixed_string& rhs) -{ - using rhs_type = std::decay_t; - using sv_type = typename rhs_type::string_view_type; - return lhs >= static_cast(rhs); -} - -#endif // FIXSTR_CPP20_SPACESHIP_OPERATOR_PRESENT - -template -basic_fixed_string(const TChar (&)[N]) -> basic_fixed_string; - -// Early GCC versions that support cNTTP were not able to deduce size_t parameter -// of basic_fixed_string when fixed_string and other typedef were just type aliases. -// That's why the following code is written in this way. -template -struct fixed_string : basic_fixed_string -{ - using basic_fixed_string::basic_fixed_string; -}; -template -fixed_string(const char (&)[N]) -> fixed_string; - -#if FIXSTR_CPP20_CHAR8T_PRESENT -template -struct fixed_u8string : basic_fixed_string -{ - using basic_fixed_string::basic_fixed_string; -}; -template -fixed_u8string(const char8_t (&)[N]) -> fixed_u8string; -#endif // FIXSTR_CPP20_CHAR8T_PRESENT - -template -struct fixed_u16string : basic_fixed_string -{ - using basic_fixed_string::basic_fixed_string; -}; -template -fixed_u16string(const char16_t (&)[N]) -> fixed_u16string; - -template -struct fixed_u32string : basic_fixed_string -{ - using basic_fixed_string::basic_fixed_string; -}; -template -fixed_u32string(const char32_t (&)[N]) -> fixed_u32string; - -template -struct fixed_wstring : basic_fixed_string -{ - using basic_fixed_string::basic_fixed_string; -}; -template -fixed_wstring(const wchar_t (&)[N]) -> fixed_wstring; - -template -constexpr basic_fixed_string operator+(const basic_fixed_string& lhs, const basic_fixed_string& rhs) -{ - basic_fixed_string result; - details::copy(lhs.begin(), lhs.end(), result.begin()); - details::copy(rhs.begin(), rhs.end(), result.begin() + N); - return result; -} - -template -constexpr basic_fixed_string operator+(const TChar (&lhs)[N], const basic_fixed_string& rhs) -{ - basic_fixed_string lhs2 = lhs; - return lhs2 + rhs; -} - -template -constexpr basic_fixed_string operator+(const basic_fixed_string& lhs, const TChar (&rhs)[M]) -{ - basic_fixed_string rhs2 = rhs; - return lhs + rhs2; -} - -namespace details -{ -template -constexpr basic_fixed_string from_char(TChar ch) -{ - basic_fixed_string fs; - fs[0] = ch; - return fs; -} -} // namespace details - -template -constexpr basic_fixed_string operator+(TChar lhs, const basic_fixed_string& rhs) -{ - return details::from_char(lhs) + rhs; -} - -template -constexpr basic_fixed_string operator+(const basic_fixed_string& lhs, TChar rhs) -{ - return lhs + details::from_char(rhs); -} - -template -std::basic_ostream& operator<<(std::basic_ostream& out, const basic_fixed_string& str) -{ - out << str.data(); - return out; -} - -} // namespace fixstr - -// hash support -namespace std -{ -template -struct hash> -{ - using argument_type = fixstr::fixed_string; - size_t operator()(const argument_type& str) const - { - using sv_t = typename argument_type::string_view_type; - return std::hash()(static_cast(str)); - } -}; - -#if FIXSTR_CPP20_CHAR8T_PRESENT -template -struct hash> -{ - using argument_type = fixstr::fixed_u8string; - size_t operator()(const argument_type& str) const - { - using sv_t = typename argument_type::string_view_type; - return std::hash()(static_cast(str)); - } -}; -#endif // FIXSTR_CPP20_CHAR8T_PRESENT - -template -struct hash> -{ - using argument_type = fixstr::fixed_u16string; - size_t operator()(const argument_type& str) const - { - using sv_t = typename argument_type::string_view_type; - return std::hash()(static_cast(str)); - } -}; - -template -struct hash> -{ - using argument_type = fixstr::fixed_u32string; - size_t operator()(const argument_type& str) const - { - using sv_t = typename argument_type::string_view_type; - return std::hash()(static_cast(str)); - } -}; - -template -struct hash> -{ - using argument_type = fixstr::fixed_wstring; - size_t operator()(const argument_type& str) const - { - using sv_t = typename argument_type::string_view_type; - return std::hash()(static_cast(str)); - } -}; - -} // namespace std - -#endif // FIXED_STRING_HPP