forward filesystem

This commit is contained in:
altalk23 2023-02-08 16:42:34 +03:00
parent 3f39341b5d
commit 4f259c6e3a
25 changed files with 349 additions and 315 deletions

View file

@ -10,7 +10,6 @@ namespace {
char const* modify_start = R"GEN(#pragma once
#include <Geode/modify/Modify.hpp>
#include <Geode/modify/Field.hpp>
#include <Geode/modify/InternalMacros.hpp>
#include <Geode/modify/Addresses.hpp>
{class_include}
using namespace geode::modifier;
@ -92,8 +91,7 @@ std::string generateModifyHeader(Root& root, ghc::filesystem::path const& single
if (fn->type == FunctionType::Normal && !used.count(fn->name)) {
used.insert(fn->name);
statics += fmt::format(
format_strings::statics_declare_identifier,
fmt::arg("function_name", fn->name)
format_strings::statics_declare_identifier, fmt::arg("function_name", fn->name)
);
}
}

View file

@ -4,7 +4,7 @@
#include <broma.hpp>
#include <fmt/format.h>
#include <fmt/ranges.h>
#include <ghc/filesystem.hpp> // bruh
#include <ghc/filesystem.hpp>
#include <fstream>
using std::istreambuf_iterator;

View file

@ -6,7 +6,7 @@
#include "picosha3.h"
#include "picosha2.h"
#include <vector>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
static std::string calculateSHA3_256(ghc::filesystem::path const& path) {
std::vector<uint8_t> s(picosha3::bits_to_bytes(256));

View file

@ -2,6 +2,6 @@
#include "Bindings.hpp"
#include "Loader.hpp"
#include "Utils.hpp"
// #include "Modify.hpp"
#include "UI.hpp"
#include "Utils.hpp"
#include "modify/Modify.hpp" // doesn't include generated modify

View file

@ -1,9 +1,7 @@
#pragma once
#include "modify/Field.hpp"
#include "modify/InternalMacros.hpp"
#include "modify/Modify.hpp"
#include <Geode/DefaultInclude.hpp>
#include <Geode/GeneratedModify.hpp>
using namespace geode::modifier;

View file

@ -28,6 +28,8 @@ namespace gd {
return std::string((char*)m_data, m_data[-1].m_len);
}
bool operator<(string const& other) const;
bool operator==(string const& other) const;
string(string const& ok);
string& operator=(char const* ok);
@ -58,142 +60,6 @@ namespace gd {
T m_value;
};
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_right;
x->m_right = y->m_left;
if (y->m_left != 0) y->m_left->m_parent = x;
y->m_parent = x->m_parent;
if (x == root) root = y;
else if (x == x->m_parent->m_left) x->m_parent->m_left = y;
else x->m_parent->m_right = y;
y->m_left = x;
x->m_parent = y;
}
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_left;
x->m_left = y->m_right;
if (y->m_right != 0) y->m_right->m_parent = x;
y->m_parent = x->m_parent;
if (x == root) root = y;
else if (x == x->m_parent->m_right) x->m_parent->m_right = y;
else x->m_parent->m_left = y;
y->m_right = x;
x->m_parent = y;
}
static void _rb_insert_rebalance(
bool const insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header
) {
_rb_tree_base*& root = header.m_parent;
x->m_parent = p;
x->m_left = 0;
x->m_right = 0;
x->m_isblack = false;
if (insert_left) {
p->m_left = x;
if (p == &header) {
header.m_parent = x;
header.m_right = x;
}
else if (p == header.m_left) {
header.m_left = x;
}
}
else {
p->m_right = x;
if (p == header.m_right) {
header.m_right = x;
}
}
while (x != root && x->m_parent->m_isblack == false) {
_rb_tree_base* const xpp = x->m_parent->m_parent;
if (x->m_parent == xpp->m_left) {
_rb_tree_base* const y = xpp->m_right;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
}
else {
if (x == x->m_parent->m_right) {
x = x->m_parent;
_rb_tree_rotate_left(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_right(xpp, root);
}
}
else {
_rb_tree_base* const y = xpp->m_left;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
}
else {
if (x == x->m_parent->m_left) {
x = x->m_parent;
_rb_tree_rotate_right(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_left(xpp, root);
}
}
}
root->m_isblack = true;
}
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw() {
if (__x->m_right != 0) {
__x = __x->m_right;
while (__x->m_left != 0)
__x = __x->m_left;
}
else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_right) {
__x = __y;
__y = __y->m_parent;
}
if (__x->m_right != __y) __x = __y;
}
return __x;
}
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw() {
if (!__x->m_isblack && __x->m_parent->m_parent == __x) __x = __x->m_right;
else if (__x->m_left != 0) {
_rb_tree_base* __y = __x->m_left;
while (__y->m_right != 0)
__y = __y->m_right;
__x = __y;
}
else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_left) {
__x = __y;
__y = __y->m_parent;
}
__x = __y;
}
return __x;
}
template <typename K, typename V>
class GEODE_DLL map {
protected:
@ -204,96 +70,25 @@ namespace gd {
public:
typedef _rb_tree_node<std::pair<K, V>>* _tree_node;
std::map<K, V> std() {
return (std::map<K, V>)(*this);
}
std::map<K, V> std();
operator std::map<K, V>() {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = static_cast<_tree_node>(&m_header);
std::map<K, V> out;
for (; iter_node != end_node;
iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
operator std::map<K, V>();
return out;
}
operator std::map<K, V>() const;
operator std::map<K, V>() const {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = (_tree_node)(&m_header);
std::map<K, V> out;
for (; iter_node != end_node;
iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
void insert(_tree_node x, _tree_node p, std::pair<K, V> const& val);
return out;
}
void insert_pair(std::pair<K, V> const& val);
void insert(_tree_node x, _tree_node p, std::pair<K, V> const& val) {
bool insert_left =
(x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
map(std::map<K, V> input);
_tree_node z = new _rb_tree_node<std::pair<K, V>>();
z->m_value = val;
void erase(_tree_node x);
_rb_insert_rebalance(insert_left, z, p, m_header);
++m_nodecount;
}
map(map const& lol);
void insert_pair(std::pair<K, V> const& val) {
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
_tree_node y = static_cast<_tree_node>(&m_header);
bool comp = true;
while (x != 0) {
y = x;
comp = val.first < x->m_value.first;
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
}
auto iter = y;
map();
if (comp) {
if (iter == static_cast<_tree_node>(m_header.m_left)) {
insert(x, y, val);
}
else {
iter = static_cast<_tree_node>(_rb_decrement(iter));
}
}
if (iter->m_value.first < val.first) {
insert(x, y, val);
}
}
map(std::map<K, V> input) {
m_header.m_isblack = false;
m_header.m_parent = 0;
m_header.m_left = &m_header;
m_header.m_right = &m_header;
for (auto i : input) {
insert_pair(i);
}
}
void erase(_tree_node x) {
while (x != 0) {
erase(static_cast<_tree_node>(x->m_right));
auto y = static_cast<_tree_node>(x->m_left);
delete y;
x = y;
}
}
map(map const& lol) : map(std::map<K, V>(lol)) {}
map() : map(std::map<K, V>()) {}
~map() {
erase(static_cast<_tree_node>(m_header.m_parent));
}
~map();
};
// template <class Type>

View file

@ -25,7 +25,7 @@ THE SOFTWARE.
#define __SUPPORT_ZIPUTILS_H__
#include <string>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include "../../platform/CCPlatformDefine.h"
#include "../../platform/CCPlatformConfig.h"
#include "../../include/ccMacros.h"

View file

@ -1,6 +1,6 @@
#pragma once
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include "../DefaultInclude.hpp"
namespace geode::dirs {

View file

@ -1,6 +1,6 @@
#pragma once
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include "../utils/Result.hpp"
#include "Log.hpp"
#include "ModInfo.hpp"

View file

@ -6,7 +6,7 @@
#include <Geode/utils/ranges.hpp>
#include <ccTypes.h>
#include <chrono>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <sstream>
#include <vector>
#include <span>

View file

@ -1,57 +0,0 @@
#include <type_traits>
/**
* Main class implementation, it has the structure
*
* class hook0Dummy;
* template<typename>
* struct hook0 {};
* namespace {
* struct hook0Parent {};
* }
* template<>
* struct GEODE_HIDDEN hook0<hook0Parent> : Modify<hook0<hook0Parent>, MenuLayer> {
* // code stuff idk
* };
*
* I tried to make the macro as verbose as it can be but
* I am bad at this stuff
*/
#define GEODE_MODIFY_DECLARE_ANONYMOUS(base, derived) \
derived##Dummy; \
template <class> \
struct derived {}; \
namespace { \
struct derived##Parent {}; \
} \
template <> \
struct GEODE_HIDDEN derived<derived##Parent> : geode::Modify<derived<derived##Parent>, base>
#define GEODE_MODIFY_DECLARE(base, derived) \
derived##Dummy; \
struct GEODE_HIDDEN derived : geode::Modify<derived, base>
#define GEODE_MODIFY_REDIRECT4(base, derived) GEODE_MODIFY_DECLARE(base, derived)
#define GEODE_MODIFY_REDIRECT3(base, derived) GEODE_MODIFY_DECLARE_ANONYMOUS(base, derived)
#define GEODE_MODIFY_REDIRECT2(base) GEODE_MODIFY_REDIRECT3(base, GEODE_CONCAT(hook, __LINE__))
#define GEODE_MODIFY_REDIRECT1(base) GEODE_MODIFY_REDIRECT2(base)
/**
* Interfaces for the class implementation
*
* class $modify(MenuLayer) {};
* class $modify(MyMenuLayerInterface, MenuLayer) {};
*/
#define GEODE_CRTP1(base) GEODE_MODIFY_REDIRECT1(base)
#define GEODE_CRTP2(derived, base) GEODE_MODIFY_REDIRECT4(base, derived)
#define $modify(...) \
GEODE_INVOKE(GEODE_CONCAT(GEODE_CRTP, GEODE_NUMBER_OF_ARGS(__VA_ARGS__)), __VA_ARGS__)
#define $(...) $modify(__VA_ARGS__)
/**
* Get current hook class without needing to name it.
* Useful for callbacks
*/
#define $cls std::remove_pointer<decltype(this)>::type

View file

@ -141,3 +141,60 @@ namespace geode {
static void onModify(auto& self) {}
};
}
/**
* Main class implementation, it has the structure
*
* class hook0Dummy;
* template<typename>
* struct hook0 {};
* namespace {
* struct hook0Parent {};
* }
* template<>
* struct GEODE_HIDDEN hook0<hook0Parent> : Modify<hook0<hook0Parent>, MenuLayer> {
* // code stuff idk
* };
*
* I tried to make the macro as verbose as it can be but
* I am bad at this stuff
*/
#define GEODE_MODIFY_DECLARE_ANONYMOUS(base, derived) \
derived##Dummy; \
template <class> \
struct derived {}; \
namespace { \
struct derived##Parent {}; \
} \
template <> \
struct GEODE_HIDDEN derived<derived##Parent> : geode::Modify<derived<derived##Parent>, base>
#define GEODE_MODIFY_DECLARE(base, derived) \
derived##Dummy; \
struct GEODE_HIDDEN derived : geode::Modify<derived, base>
#define GEODE_MODIFY_REDIRECT4(base, derived) GEODE_MODIFY_DECLARE(base, derived)
#define GEODE_MODIFY_REDIRECT3(base, derived) GEODE_MODIFY_DECLARE_ANONYMOUS(base, derived)
#define GEODE_MODIFY_REDIRECT2(base) GEODE_MODIFY_REDIRECT3(base, GEODE_CONCAT(hook, __LINE__))
#define GEODE_MODIFY_REDIRECT1(base) GEODE_MODIFY_REDIRECT2(base)
/**
* Interfaces for the class implementation
*
* class $modify(MenuLayer) {};
* class $modify(MyMenuLayerInterface, MenuLayer) {};
*/
#define GEODE_CRTP1(base) GEODE_MODIFY_REDIRECT1(base)
#define GEODE_CRTP2(derived, base) GEODE_MODIFY_REDIRECT4(base, derived)
#define $modify(...) \
GEODE_INVOKE(GEODE_CONCAT(GEODE_CRTP, GEODE_NUMBER_OF_ARGS(__VA_ARGS__)), __VA_ARGS__)
#define $(...) $modify(__VA_ARGS__)
/**
* Get current hook class without needing to name it.
* Useful for callbacks
* this is a camila moment if you ask me
*/
#define $cls std::remove_pointer<decltype(this)>::type

View file

@ -5,7 +5,7 @@
#include <json.hpp>
#include <Geode/DefaultInclude.hpp>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <string>
#include <unordered_set>

View file

@ -8,7 +8,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
// for some reason std::filesystem::path doesn't have std::hash defined in C++17
// and ghc seems to have inherited this limitation

View file

@ -5,7 +5,7 @@
#include "Result.hpp"
#include "general.hpp"
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <mutex>
namespace geode::utils::web {

View file

@ -1,4 +1,4 @@
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <mach-o/dyld.h>
#include <unistd.h>
#include <dlfcn.h>

View file

@ -1,6 +1,6 @@
#include <Windows.h>
#include <iostream>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
void showError(std::string const& error) {
MessageBoxA(nullptr, error.c_str(), "Error Loading Geode", MB_ICONERROR);

View file

@ -4,16 +4,15 @@
USE_GEODE_NAMESPACE();
#include <Geode/modify/InternalMacros.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/modify/Modify.hpp>
$execute {
// this replaces the call to __dynamic_cast with a call to our own
// this is needed because the transitions in cocos uses dynamic cast to check
// layers, which fail on user layers due to typeinfo not matching
(void)Mod::get()->patch(
reinterpret_cast<void*>(base::get() + 0x603948),
toByteArray(&cast::typeinfoCastInternal)
reinterpret_cast<void*>(base::get() + 0x603948), toByteArray(&cast::typeinfoCastInternal)
);
}

View file

@ -3,8 +3,8 @@
#ifdef GEODE_IS_WINDOWS
#include <Geode/modify/InternalMacros.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/modify/Modify.hpp>
USE_GEODE_NAMESPACE();
@ -19,16 +19,18 @@ static void __cdecl fixedErrorHandler(int code, char const* description) {
fmt::format(
"GLFWError #{}: {}\nPlease contact the "
"Geode Development Team for more information.",
code, description
).c_str(),
"OpenGL Error", MB_ICONERROR
code,
description
)
.c_str(),
"OpenGL Error",
MB_ICONERROR
);
}
$execute {
(void)Mod::get()->patch(
reinterpret_cast<void*>(geode::base::getCocos() + 0x19feec),
toByteArray(&fixedErrorHandler)
reinterpret_cast<void*>(geode::base::getCocos() + 0x19feec), toByteArray(&fixedErrorHandler)
);
}

View file

@ -2,7 +2,7 @@
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/general.hpp>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <functional>
#include <string>

View file

@ -1,7 +1,7 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <string>
/**

View file

@ -8,6 +8,7 @@
#include <Geode/loader/SettingEvent.hpp>
#include <Geode/loader/ModJsonTest.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <ghc/fs_impl.hpp>
#include <array>
USE_GEODE_NAMESPACE();

View file

@ -2,10 +2,10 @@
#ifdef GEODE_IS_MACOS
#include <array>
#include <ghc/filesystem.hpp>
#include <array>
#include <ghc/fs_fwd.hpp>
#include <Foundation/Foundation.h>
#include <Foundation/Foundation.h>
bool crashlog::setupPlatformHandler() {
return true;

View file

@ -6,8 +6,7 @@ namespace gd {
namespace {
static inline auto emptyInternalString() {
return reinterpret_cast<_internal_string*>(
*reinterpret_cast<uintptr_t*>(geode::base::get() + 0x6030d0) +
sizeof(_internal_string)
*reinterpret_cast<uintptr_t*>(geode::base::get() + 0x6030d0) + sizeof(_internal_string)
);
}
}
@ -50,11 +49,253 @@ namespace gd {
}
}
bool string::operator==(string const& other) const {
if (size() != other.size()) return false;
return strcmp(c_str(), other.c_str()) == 0;
bool string::operator<(string const& other) const {
return std::string(*this) < std::string(other);
}
bool string::operator==(string const& other) const {
return std::string(*this) == std::string(other);
}
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_right;
x->m_right = y->m_left;
if (y->m_left != 0) y->m_left->m_parent = x;
y->m_parent = x->m_parent;
if (x == root) root = y;
else if (x == x->m_parent->m_left) x->m_parent->m_left = y;
else x->m_parent->m_right = y;
y->m_left = x;
x->m_parent = y;
}
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
_rb_tree_base* const y = x->m_left;
x->m_left = y->m_right;
if (y->m_right != 0) y->m_right->m_parent = x;
y->m_parent = x->m_parent;
if (x == root) root = y;
else if (x == x->m_parent->m_right) x->m_parent->m_right = y;
else x->m_parent->m_left = y;
y->m_right = x;
x->m_parent = y;
}
static void _rb_insert_rebalance(
bool const insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header
) {
_rb_tree_base*& root = header.m_parent;
x->m_parent = p;
x->m_left = 0;
x->m_right = 0;
x->m_isblack = false;
if (insert_left) {
p->m_left = x;
if (p == &header) {
header.m_parent = x;
header.m_right = x;
}
else if (p == header.m_left) {
header.m_left = x;
}
}
else {
p->m_right = x;
if (p == header.m_right) {
header.m_right = x;
}
}
while (x != root && x->m_parent->m_isblack == false) {
_rb_tree_base* const xpp = x->m_parent->m_parent;
if (x->m_parent == xpp->m_left) {
_rb_tree_base* const y = xpp->m_right;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
}
else {
if (x == x->m_parent->m_right) {
x = x->m_parent;
_rb_tree_rotate_left(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_right(xpp, root);
}
}
else {
_rb_tree_base* const y = xpp->m_left;
if (y && y->m_isblack == false) {
x->m_parent->m_isblack = true;
y->m_isblack = true;
xpp->m_isblack = false;
x = xpp;
}
else {
if (x == x->m_parent->m_left) {
x = x->m_parent;
_rb_tree_rotate_right(x, root);
}
x->m_parent->m_isblack = true;
xpp->m_isblack = false;
_rb_tree_rotate_left(xpp, root);
}
}
}
root->m_isblack = true;
}
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw() {
if (__x->m_right != 0) {
__x = __x->m_right;
while (__x->m_left != 0)
__x = __x->m_left;
}
else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_right) {
__x = __y;
__y = __y->m_parent;
}
if (__x->m_right != __y) __x = __y;
}
return __x;
}
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw() {
if (!__x->m_isblack && __x->m_parent->m_parent == __x) __x = __x->m_right;
else if (__x->m_left != 0) {
_rb_tree_base* __y = __x->m_left;
while (__y->m_right != 0)
__y = __y->m_right;
__x = __y;
}
else {
_rb_tree_base* __y = __x->m_parent;
while (__x == __y->m_left) {
__x = __y;
__y = __y->m_parent;
}
__x = __y;
}
return __x;
}
template <class K, class V>
std::map<K, V> map<K, V>::std() {
return (std::map<K, V>)(*this);
}
template <class K, class V>
map<K, V>::operator std::map<K, V>() {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = static_cast<_tree_node>(&m_header);
std::map<K, V> out;
for (; iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
template <class K, class V>
map<K, V>::operator std::map<K, V>() const {
auto iter_node = static_cast<_tree_node>(m_header.m_left);
auto end_node = (_tree_node)(&m_header);
std::map<K, V> out;
for (; iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
out[iter_node->m_value.first] = iter_node->m_value.second;
}
return out;
}
template <class K, class V>
void map<K, V>::insert(_tree_node x, _tree_node p, std::pair<K, V> const& val) {
bool insert_left =
(x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
_tree_node z = new _rb_tree_node<std::pair<K, V>>();
z->m_value = val;
_rb_insert_rebalance(insert_left, z, p, m_header);
++m_nodecount;
}
template <class K, class V>
void map<K, V>::insert_pair(std::pair<K, V> const& val) {
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
_tree_node y = static_cast<_tree_node>(&m_header);
bool comp = true;
while (x != 0) {
y = x;
comp = val.first < x->m_value.first;
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
}
auto iter = y;
if (comp) {
if (iter == static_cast<_tree_node>(m_header.m_left)) {
insert(x, y, val);
}
else {
iter = static_cast<_tree_node>(_rb_decrement(iter));
}
}
if (iter->m_value.first < val.first) {
insert(x, y, val);
}
}
template <class K, class V>
map<K, V>::map(std::map<K, V> input) {
m_header.m_isblack = false;
m_header.m_parent = 0;
m_header.m_left = &m_header;
m_header.m_right = &m_header;
for (auto i : input) {
insert_pair(i);
}
}
template <class K, class V>
void map<K, V>::erase(_tree_node x) {
while (x != 0) {
erase(static_cast<_tree_node>(x->m_right));
auto y = static_cast<_tree_node>(x->m_left);
delete y;
x = y;
}
}
template <class K, class V>
map<K, V>::map(map const& lol) : map(std::map<K, V>(lol)) {}
template <class K, class V>
map<K, V>::map() : map(std::map<K, V>()) {}
template <class K, class V>
map<K, V>::~map() {
erase(static_cast<_tree_node>(m_header.m_parent));
}
template class map<int, int>;
template class map<gd::string, gd::string>;
template class map<gd::string, bool>;
template class map<short, bool>;
}
#endif

View file

@ -6,7 +6,7 @@
USE_GEODE_NAMESPACE();
#include "nfdwin.hpp"
#include <ghc/filesystem.hpp>
#include <ghc/fs_fwd.hpp>
#include <Windows.h>
#include <iostream>
#include <shlwapi.h>