mirror of
https://github.com/edubart/otclient.git
synced 2025-12-14 04:49:45 +01:00
Rework stdext classes
Implement new classes: * stdext::any => ligher replacement for boost::any * stdext::packed_any => like any but optimized to use less memory * stdext::shared_object => ligher replacement for std::shared_ptr * stdext::shared_object_ptr => replacement for boost::intrusive_ptr * stdext::fast_storage => for storing dynamic data * stdext::packed_storage => same but with less memory * stdext::packed_vector => std::vector with less memory Compiling should be a little faster now because global boost including is not needed anymore
This commit is contained in:
77
src/framework/stdext/any.h
Normal file
77
src/framework/stdext/any.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_ANY_H
|
||||
#define STDEXT_ANY_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
class any {
|
||||
public:
|
||||
struct placeholder {
|
||||
virtual ~placeholder() { }
|
||||
virtual const std::type_info& type() const = 0;
|
||||
virtual placeholder* clone() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct holder : public placeholder {
|
||||
holder(const T& value) : held(value) { }
|
||||
const std::type_info& type() const { return typeid(T); }
|
||||
placeholder* clone() const { return new holder(held); }
|
||||
T held;
|
||||
private:
|
||||
holder& operator=(const holder &);
|
||||
};
|
||||
|
||||
placeholder* content;
|
||||
|
||||
any() : content(nullptr) { }
|
||||
any(const any& other) : content(other.content ? other.content->clone() : nullptr) { }
|
||||
template<typename T> any(const T& value) : content(new holder<T>(value)) { }
|
||||
~any() { if(content) delete content; }
|
||||
|
||||
any& swap(any& rhs) { std::swap(content, rhs.content); return *this; }
|
||||
|
||||
template<typename T> any& operator=(const T& rhs) { any(rhs).swap(*this); return *this; }
|
||||
any& operator=(any rhs) { rhs.swap(*this); return *this; }
|
||||
|
||||
bool empty() const { return !content; }
|
||||
template<typename T> const T& cast() const;
|
||||
const std::type_info & type() const { return content ? content->type() : typeid(void); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const T& any_cast(const any& operand) {
|
||||
assert(operand.type() == typeid(T));
|
||||
return static_cast<any::holder<T>*>(operand.content)->held;
|
||||
}
|
||||
|
||||
template<typename T> const T& any::cast() const { return any_cast<T>(*this); }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -23,15 +23,13 @@
|
||||
#ifndef STDEXT_CAST_H
|
||||
#define STDEXT_CAST_H
|
||||
|
||||
namespace stdext {
|
||||
template<typename R, typename T> R safe_cast(const T& t);
|
||||
template<typename R, typename T> R unsafe_cast(const T& t, R def = R());
|
||||
}
|
||||
|
||||
#include "string.h"
|
||||
#include "exception.h"
|
||||
#include "demangle.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
// cast a type to another type
|
||||
@@ -142,7 +140,9 @@ public:
|
||||
virtual ~cast_exception() throw() { }
|
||||
template<class T, class R>
|
||||
void update_what() {
|
||||
m_what = format("failed to cast value of type '%s' to type '%s'", demangle_type<T>(), demangle_type<R>());
|
||||
std::stringstream ss;
|
||||
ss << "failed to cast value of type '" << demangle_type<T>() << "' to type '" << demangle_type<R>() << "'";
|
||||
m_what = ss.str();
|
||||
}
|
||||
virtual const char* what() const throw() { return m_what.c_str(); }
|
||||
private:
|
||||
@@ -163,14 +163,15 @@ R safe_cast(const T& t) {
|
||||
|
||||
// cast a type to another type, cast errors are ignored
|
||||
template<typename R, typename T>
|
||||
R unsafe_cast(const T& t, R def) {
|
||||
R unsafe_cast(const T& t, R def = R()) {
|
||||
try {
|
||||
return safe_cast<R,T>(t);
|
||||
} catch(cast_exception& e) {
|
||||
std::cout << "CAST ERROR: " << e.what() << std::endl;
|
||||
std::cerr << "CAST ERROR: " << e.what() << std::endl;
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#ifdef __clang__
|
||||
// clang is supported
|
||||
#undef _GLIBCXX_USE_FLOAT128
|
||||
#elif defined(__GNUC__)
|
||||
#if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
|
||||
#error "Sorry, you need gcc 4.6 or greater to compile."
|
||||
|
||||
44
src/framework/stdext/demangle.cpp
Normal file
44
src/framework/stdext/demangle.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "demangle.h"
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
const char* demangle_name(const char* name)
|
||||
{
|
||||
size_t len;
|
||||
int status;
|
||||
static char buffer[1024];
|
||||
char* demangled = abi::__cxa_demangle(name, 0, &len, &status);
|
||||
if(demangled) {
|
||||
strcpy(buffer, demangled);
|
||||
free(demangled);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,29 +23,16 @@
|
||||
#ifndef STDEXT_DEMANGLE_H
|
||||
#define STDEXT_DEMANGLE_H
|
||||
|
||||
#include <cxxabi.h>
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
/// Demangle names for GNU g++ compiler
|
||||
inline std::string demangle_name(const char* name) {
|
||||
size_t len;
|
||||
int status;
|
||||
std::string ret;
|
||||
char* demangled = abi::__cxa_demangle(name, 0, &len, &status);
|
||||
if(demangled) {
|
||||
ret = demangled;
|
||||
free(demangled);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const char* demangle_name(const char* name);
|
||||
|
||||
/// Returns the name of a type
|
||||
template<typename T>
|
||||
std::string demangle_type() {
|
||||
return demangle_name(typeid(T).name());
|
||||
}
|
||||
template<typename T> std::string demangle_type() { return demangle_name(typeid(T).name()); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,30 +27,13 @@
|
||||
|
||||
namespace stdext {
|
||||
|
||||
namespace dumper {
|
||||
|
||||
struct dumper_dummy {
|
||||
~dumper_dummy() { std::cout << std::endl; }
|
||||
template<class T>
|
||||
dumper_dummy& operator<<(const T& v) {
|
||||
std::cout << v << " ";
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct dumper_util {
|
||||
dumper_util() { }
|
||||
template<class T>
|
||||
dumper_dummy operator<<(const T& v) const {
|
||||
dumper_dummy d;
|
||||
d << v;
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const static dumper::dumper_util dump;
|
||||
static struct {
|
||||
struct dumper_dummy {
|
||||
~dumper_dummy() { std::cout << std::endl; }
|
||||
template<class T> dumper_dummy& operator<<(const T& v) { std::cout << v << " "; return *this; }
|
||||
};
|
||||
template<class T> dumper_dummy operator<<(const T& v) const { dumper_dummy d; d << v; return d; }
|
||||
} dump;
|
||||
|
||||
}
|
||||
|
||||
|
||||
53
src/framework/stdext/dynamic_storage.h
Normal file
53
src/framework/stdext/dynamic_storage.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_DYNAMICSTORAGE_H
|
||||
#define STDEXT_DYNAMICSTORAGE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "any.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
template<typename Key>
|
||||
class dynamic_storage {
|
||||
public:
|
||||
template<typename T> void set(const Key& k, const T& value) { m_map[k] = value; }
|
||||
template<typename T> T get(const Key& k) const {
|
||||
auto it = m_map.find(k);
|
||||
if(it != m_map.end())
|
||||
return any_cast<T>(it->second);
|
||||
return T();
|
||||
}
|
||||
bool has(const Key& k) const { return m_map.find(k) != m_map.end(); }
|
||||
|
||||
std::size_t size() const { return m_map.size(); }
|
||||
void clear() { m_map.clear(); }
|
||||
|
||||
private:
|
||||
std::unordered_map<Key, any> m_map;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -34,9 +34,7 @@ public:
|
||||
exception() { }
|
||||
exception(const std::string& what) : m_what(what) { }
|
||||
virtual ~exception() throw() { };
|
||||
|
||||
virtual const char* what() const throw() { return m_what.c_str(); }
|
||||
|
||||
protected:
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
86
src/framework/stdext/format.h
Normal file
86
src/framework/stdext/format.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_FORMAT_H
|
||||
#define STDEXT_FORMAT_H
|
||||
|
||||
#include "traits.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <tuple>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
template<class T> void print_ostream(std::ostringstream& stream, const T& last) { stream << last; }
|
||||
template<class T, class... Args>
|
||||
void print_ostream(std::ostringstream& stream, const T& first, const Args&... rest) { stream << "\t" << first; print_ostream(stream, rest...); }
|
||||
template<class... T>
|
||||
|
||||
/// Utility for printing variables just like lua
|
||||
void print(const T&... args) { std::ostringstream buf; print_ostream(buf, args...); std::cout << buf.str() << std::endl; }
|
||||
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_integral<T>::value ||
|
||||
std::is_pointer<T>::value ||
|
||||
std::is_floating_point<T>::value ||
|
||||
std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; }
|
||||
inline const char *sprintf_cast(const std::string& s) { return s.c_str(); }
|
||||
|
||||
template<int N> struct expand_snprintf {
|
||||
template<typename Tuple, typename... Args> static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
|
||||
return expand_snprintf<N-1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N-1>(tuple)), args...); }};
|
||||
template<> struct expand_snprintf<0> {
|
||||
template<typename Tuple, typename... Args> static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
|
||||
return snprintf(s, maxlen, format, args...); }};
|
||||
|
||||
/// Improved snprintf that accepts std::string and other types
|
||||
template<typename... Args>
|
||||
int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) {
|
||||
std::tuple<typename replace_extent<Args>::type...> tuple(args...);
|
||||
return expand_snprintf<std::tuple_size<decltype(tuple)>::value>::call(s, maxlen, format, tuple);
|
||||
}
|
||||
|
||||
/// Format strings with the sprintf style, accepting std::string and string convertible types for %s
|
||||
template<typename... Args>
|
||||
std::string format(const std::string& format, const Args&... args) {
|
||||
int n, size = 1024;
|
||||
std::string str;
|
||||
while(true) {
|
||||
str.resize(size);
|
||||
n = snprintf(&str[0], size, format.c_str(), args...);
|
||||
assert(n != -1);
|
||||
if(n < size) {
|
||||
str.resize(n);
|
||||
return str;
|
||||
}
|
||||
size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
60
src/framework/stdext/math.cpp
Normal file
60
src/framework/stdext/math.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "math.h"
|
||||
#include <random>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
uint32_t adler32(const uint8_t *buffer, size_t size) {
|
||||
register size_t a = 1, b = 0, tlen;
|
||||
while(size > 0) {
|
||||
tlen = size > 5552 ? 5552 : size;
|
||||
size -= tlen;
|
||||
do {
|
||||
a += *buffer++;
|
||||
b += a;
|
||||
} while (--tlen);
|
||||
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return (b << 16) | a;
|
||||
}
|
||||
|
||||
long random_range(long min, long max)
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<long> dis(0, 2147483647);
|
||||
return min + (dis(gen) % (max - min + 1));
|
||||
}
|
||||
|
||||
float random_range(float min, float max)
|
||||
{
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_real_distribution<float> dis(0.0, 1.0);
|
||||
return min + (max - min)*dis(gen);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,65 +24,24 @@
|
||||
#define STDEXT_MATH_H
|
||||
|
||||
#include "types.h"
|
||||
#include <random>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
inline uint32 adler32(const uint8 *buffer, uint16 size) {
|
||||
register uint32 a = 1, b = 0, tlen;
|
||||
while(size > 0) {
|
||||
tlen = size > 5552 ? 5552 : size;
|
||||
size -= tlen;
|
||||
do {
|
||||
a += *buffer++;
|
||||
b += a;
|
||||
} while (--tlen);
|
||||
inline bool is_power_of_two(size_t v) { return ((v != 0) && !(v & (v - 1))); }
|
||||
inline size_t to_power_of_two(size_t v) { if(v == 0) return 0; size_t r = 1; while(r < v && r != 0xffffffff) r <<= 1; return r; }
|
||||
|
||||
a %= 65521;
|
||||
b %= 65521;
|
||||
}
|
||||
return (b << 16) | a;
|
||||
}
|
||||
inline uint16_t readLE16(const uchar *addr) { return (uint16_t)addr[1] << 8 | addr[0]; }
|
||||
inline uint32_t readLE32(const uchar *addr) { return (uint32_t)readLE16(addr + 2) << 16 | readLE16(addr); }
|
||||
inline uint64_t readLE64(const uchar *addr) { return (uint64_t)readLE32(addr + 4) << 32 | readLE32(addr); }
|
||||
|
||||
inline bool is_power_of_two(uint32 v) {
|
||||
return ((v != 0) && !(v & (v - 1)));
|
||||
}
|
||||
inline void writeLE16(uchar *addr, uint16_t value) { addr[1] = value >> 8; addr[0] = (uint8_t)value; }
|
||||
inline void writeLE32(uchar *addr, uint32_t value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16_t)value); }
|
||||
inline void writeLE64(uchar *addr, uint64_t value) { writeLE32(addr + 4, value >> 32); writeLE32(addr, (uint32_t)value); }
|
||||
|
||||
inline uint32 to_power_of_two(uint32 v) {
|
||||
if(v == 0)
|
||||
return 0;
|
||||
uint32 r = 1;
|
||||
while(r < v && r != 0xffffffff)
|
||||
r <<= 1;
|
||||
return r;
|
||||
}
|
||||
uint32_t adler32(const uint8_t *buffer, size_t size);
|
||||
|
||||
inline uint16 readLE16(const uchar *addr) { return (uint16)addr[1] << 8 | addr[0]; }
|
||||
inline uint32 readLE32(const uchar *addr) { return (uint32)readLE16(addr + 2) << 16 | readLE16(addr); }
|
||||
inline uint64 readLE64(const uchar *addr) { return (uint64)readLE32(addr + 4) << 32 | readLE32(addr); }
|
||||
|
||||
inline void writeLE16(uchar *addr, uint16 value) { addr[1] = value >> 8; addr[0] = (uint8)value; }
|
||||
inline void writeLE32(uchar *addr, uint32 value) { writeLE16(addr + 2, value >> 16); writeLE16(addr, (uint16)value); }
|
||||
inline void writeLE64(uchar *addr, uint64 value) { writeLE32(addr + 4, value >> 32); writeLE32(addr, (uint32)value); }
|
||||
|
||||
template<typename T>
|
||||
T random_range(T min, T max);
|
||||
|
||||
template<>
|
||||
inline int random_range<int>(int min, int max) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<int> dis(0, 2147483647);
|
||||
return min + (dis(gen) % (max - min + 1));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline float random_range<float>(float min, float max) {
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_real_distribution<float> dis(0.0, 1.0);
|
||||
return min + (max - min)*dis(gen);
|
||||
}
|
||||
long random_range(long min, long max);
|
||||
float random_range(float min, float max);
|
||||
|
||||
}
|
||||
|
||||
|
||||
113
src/framework/stdext/packed_any.h
Normal file
113
src/framework/stdext/packed_any.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_PACKEDANY_H
|
||||
#define STDEXT_PACKEDANY_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
// disable memory alignment
|
||||
#pragma pack(push,1)
|
||||
|
||||
template<typename T>
|
||||
struct can_pack_in_any : std::integral_constant<bool,
|
||||
(sizeof(T) <= sizeof(void*) && std::is_trivial<T>::value)> {};
|
||||
|
||||
// improved to use less memory
|
||||
class packed_any {
|
||||
public:
|
||||
struct placeholder {
|
||||
virtual ~placeholder() { }
|
||||
virtual const std::type_info& type() const = 0;
|
||||
virtual placeholder* clone() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct holder : public placeholder {
|
||||
holder(const T& value) : held(value) { }
|
||||
const std::type_info& type() const { return typeid(T); }
|
||||
placeholder* clone() const { return new holder(held); }
|
||||
T held;
|
||||
private:
|
||||
holder& operator=(const holder &);
|
||||
};
|
||||
|
||||
placeholder* content;
|
||||
bool scalar;
|
||||
|
||||
packed_any() :
|
||||
content(nullptr), scalar(false) { }
|
||||
packed_any(const packed_any& other) :
|
||||
content(!other.scalar && other.content ? other.content->clone() : other.content),
|
||||
scalar(other.scalar) { }
|
||||
template<typename T>
|
||||
packed_any(const T& value, typename std::enable_if<(can_pack_in_any<T>::value)>::type* = nullptr) :
|
||||
content(reinterpret_cast<placeholder*>(static_cast<std::size_t>(value))), scalar(true) { }
|
||||
template<typename T>
|
||||
packed_any(const T& value, typename std::enable_if<!(can_pack_in_any<T>::value)>::type* = nullptr) :
|
||||
content(new holder<T>(value)), scalar(false) { }
|
||||
~packed_any()
|
||||
{ if(!scalar && content) delete content; }
|
||||
|
||||
packed_any& swap(packed_any& rhs) { std::swap(content, rhs.content); std::swap(scalar, rhs.scalar); return *this; }
|
||||
|
||||
template<typename T> packed_any& operator=(const T& rhs) { packed_any(rhs).swap(*this); return *this; }
|
||||
packed_any& operator=(packed_any rhs) { rhs.swap(*this); return *this; }
|
||||
|
||||
bool empty() const { return !scalar && !content; }
|
||||
template<typename T> T cast() const;
|
||||
const std::type_info& type() const {
|
||||
if(scalar)
|
||||
return content ? content->type() : typeid(void);
|
||||
else
|
||||
return typeid(std::size_t);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T packed_any_cast(const packed_any& operand) {
|
||||
if(operand.scalar) {
|
||||
union {
|
||||
T v;
|
||||
packed_any::placeholder* content;
|
||||
};
|
||||
content = operand.content;
|
||||
return v;
|
||||
} else {
|
||||
assert(operand.type() == typeid(T));
|
||||
return static_cast<packed_any::holder<T>*>(operand.content)->held;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> T packed_any::cast() const { return packed_any_cast<T>(*this); }
|
||||
|
||||
// restore memory alignment
|
||||
#pragma pack(pop)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -20,63 +20,73 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef STDEXT_ATTRIBSTORAGE_H
|
||||
#define STDEXT_ATTRIBSTORAGE_H
|
||||
#ifndef STDEXT_PACKEDSTORAGE_H
|
||||
#define STDEXT_PACKEDSTORAGE_H
|
||||
|
||||
#include "types.h"
|
||||
#include <tuple>
|
||||
#include <boost/any.hpp>
|
||||
#include "packed_any.h"
|
||||
|
||||
namespace stdext {
|
||||
|
||||
// disable memory alignment
|
||||
#pragma pack(push,1)
|
||||
|
||||
// this class was designed to use less memory as possible
|
||||
namespace stdext {
|
||||
class attrib_storage {
|
||||
template<typename Key, typename SizeType = uint8>
|
||||
class packed_storage {
|
||||
struct value_pair {
|
||||
Key id;
|
||||
packed_any value;
|
||||
};
|
||||
|
||||
public:
|
||||
attrib_storage() : m_attribs(nullptr), m_size(0) { }
|
||||
~attrib_storage() { if(m_attribs) delete[] m_attribs; }
|
||||
packed_storage() : m_values(nullptr), m_size(0) { }
|
||||
~packed_storage() { if(m_values) delete[] m_values; }
|
||||
|
||||
template<typename T>
|
||||
void set(uint8 id, T value) {
|
||||
bool done = false;
|
||||
for(int i=0;i<m_size;++i) {
|
||||
if(std::get<0>(m_attribs[i]) == id) {
|
||||
std::get<1>(m_attribs[i]) = value;
|
||||
done = true;
|
||||
break;
|
||||
void set(Key id, T value) {
|
||||
for(SizeType i=0;i<m_size;++i) {
|
||||
if(m_values[i].id == id) {
|
||||
m_values[i].value = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!done) {
|
||||
auto attribs = new std::tuple<uint8, boost::any>[m_size+1];
|
||||
if(m_size > 0) {
|
||||
for(int i=0;i<m_size;++i)
|
||||
attribs[i] = m_attribs[i];
|
||||
delete[] m_attribs;
|
||||
}
|
||||
m_attribs = attribs;
|
||||
m_attribs[m_size++] = std::make_tuple(id, value);
|
||||
auto tmp = new value_pair[m_size+1];
|
||||
if(m_size > 0) {
|
||||
std::copy(m_values, m_values + m_size, tmp);
|
||||
delete[] m_values;
|
||||
}
|
||||
m_values = tmp;
|
||||
m_values[m_size++] = { id, packed_any(value) };
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T get(uint8 id) const {
|
||||
for(int i=0;i<m_size;++i)
|
||||
if(std::get<0>(m_attribs[i]) == id)
|
||||
return boost::any_cast<T>(std::get<1>(m_attribs[i]));
|
||||
T get(Key id) const {
|
||||
for(SizeType i=0;i<m_size;++i)
|
||||
if(m_values[i].id == id)
|
||||
return packed_any_cast<T>(m_values[i].value);
|
||||
return T();
|
||||
}
|
||||
|
||||
bool has(uint8 id) const {
|
||||
for(int i=0;i<m_size;++i)
|
||||
if(std::get<0>(m_attribs[i]) == id)
|
||||
bool has(Key id) const {
|
||||
for(SizeType i=0;i<m_size;++i)
|
||||
if(m_values[i].id == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if(m_values)
|
||||
delete [] m_values;
|
||||
m_values = nullptr;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
std::size_t size() { return m_size; }
|
||||
|
||||
private:
|
||||
std::tuple<uint8, boost::any>* m_attribs;
|
||||
uint8 m_size;
|
||||
value_pair *m_values;
|
||||
SizeType m_size;
|
||||
};
|
||||
|
||||
// restore memory alignment
|
||||
157
src/framework/stdext/packed_vector.h
Normal file
157
src/framework/stdext/packed_vector.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_PACKEDVECTOR_H
|
||||
#define STDEXT_PACKEDVECTOR_H
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
// disable memory alignment
|
||||
#pragma pack(push,1)
|
||||
|
||||
template<class T, class U = uint8_t>
|
||||
class packed_vector
|
||||
{
|
||||
public:
|
||||
typedef U size_type;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
packed_vector() : m_size(0), m_data(nullptr) { }
|
||||
packed_vector(size_type size) : m_size(size), m_data(new T[size]) { }
|
||||
packed_vector(size_type size, const T& value) : m_size(size), m_data(new T[size](value)) { }
|
||||
template <class InputIterator>
|
||||
packed_vector(InputIterator first, InputIterator last) : m_size(last - first), m_data(new T[m_size]) { std::copy(first, last, m_data); }
|
||||
packed_vector(const packed_vector<T>& other) : m_size(other.m_size), m_data(new T[other.m_size]) { std::copy(other.begin(), other.end(), m_data); }
|
||||
~packed_vector() { if(m_data) delete[] m_data; }
|
||||
|
||||
packed_vector<T,U>& operator=(packed_vector<T,U> other) { other.swap(*this); return *this; }
|
||||
|
||||
iterator begin() { return m_data; }
|
||||
const_iterator begin() const { return m_data; }
|
||||
const_iterator cbegin() const { return m_data; }
|
||||
iterator end() { return m_data + m_size; }
|
||||
const_iterator end() const { return m_data + m_size; }
|
||||
const_iterator cend() const { return m_data + m_size; }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const { return reverse_iterator(end()); }
|
||||
const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
size_type size() const { return m_size; }
|
||||
bool empty() const { return m_size == 0; }
|
||||
|
||||
T& operator[](size_type i) { return m_data[i]; }
|
||||
const T& operator[](size_type i) const { return m_data[i]; }
|
||||
T& at(size_type i) { return m_data[i]; }
|
||||
const T& at(size_type i) const { return m_data[i]; }
|
||||
|
||||
T& front() { return m_data[0]; }
|
||||
const T& front() const { return m_data[0]; }
|
||||
T& back() { return m_data[m_size-1]; }
|
||||
const T& back() const { return m_data[m_size-1]; }
|
||||
|
||||
T *data() { return m_data; }
|
||||
const T *data() const { return m_data; }
|
||||
|
||||
void clear() {
|
||||
if(m_data) {
|
||||
delete[] m_data;
|
||||
m_data = nullptr;
|
||||
}
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void resize(size_type size) {
|
||||
clear();
|
||||
if(size > 0) {
|
||||
m_data = new T[size];
|
||||
m_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void push_back(const T& x) {
|
||||
T *tmp = new T[m_size+1];
|
||||
std::copy(m_data, m_data + m_size, tmp);
|
||||
tmp[m_size] = x;
|
||||
delete[] m_data;
|
||||
m_data = tmp;
|
||||
m_size++;
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
T *tmp = new T[m_size-1];
|
||||
std::copy(m_data, m_data + m_size - 1, tmp);
|
||||
delete[] m_data;
|
||||
m_data = tmp;
|
||||
m_size--;
|
||||
}
|
||||
|
||||
iterator insert(const_iterator position, const T& x) {
|
||||
T *tmp = new T[m_size+1];
|
||||
size_type i = position - m_data;
|
||||
std::copy(m_data, m_data + i, tmp);
|
||||
tmp[i] = x;
|
||||
std::copy(m_data + i, m_data + m_size, tmp + i + 1);
|
||||
delete[] m_data;
|
||||
m_data = tmp;
|
||||
m_size++;
|
||||
return tmp + i;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position) {
|
||||
T *tmp = new T[m_size-1];
|
||||
size_type i = position - m_data;
|
||||
std::copy(m_data, m_data + i, tmp);
|
||||
std::copy(m_data + i + 1, m_data + m_size, tmp + i);
|
||||
delete[] m_data;
|
||||
m_data = tmp;
|
||||
m_size--;
|
||||
return tmp + i;
|
||||
}
|
||||
|
||||
void swap(packed_vector<T,U>& other) { std::swap(m_size, other.m_size); std::swap(m_data, other.m_data); return *this; }
|
||||
|
||||
operator std::vector<T>() const { return std::vector<T>(begin(), end()); }
|
||||
|
||||
private:
|
||||
size_type m_size;
|
||||
T* m_data;
|
||||
};
|
||||
|
||||
// restore memory alignment
|
||||
#pragma pack(pop)
|
||||
|
||||
namespace std {
|
||||
template<class T, class U> void swap(stdext::packed_vector<T,U>& lhs, stdext::packed_vector<T,U>& rhs) { lhs.swap(rhs); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -23,55 +23,107 @@
|
||||
#ifndef STDEXT_SHARED_OBJECT_H
|
||||
#define STDEXT_SHARED_OBJECT_H
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
template<class T>
|
||||
class shared_object_ptr;
|
||||
|
||||
typedef unsigned int refcount_t;
|
||||
|
||||
class shared_object
|
||||
{
|
||||
public:
|
||||
shared_object() : m_refs(0) { }
|
||||
virtual ~shared_object() { }
|
||||
void add_ref() { ++m_refs; assert(m_refs != 0xffffffff); }
|
||||
void dec_ref() {
|
||||
if(--m_refs == 0)
|
||||
boost::checked_delete(this);
|
||||
}
|
||||
bool is_unique_ref() { return m_refs == 1; }
|
||||
unsigned long ref_count() { return m_refs; }
|
||||
template<typename T>
|
||||
boost::intrusive_ptr<T> self_cast() { return boost::intrusive_ptr<T>(static_cast<T*>(this)); }
|
||||
template<typename T>
|
||||
boost::intrusive_ptr<T> dynamic_self_cast() { return boost::intrusive_ptr<T>(dynamic_cast<T*>(this)); }
|
||||
void dec_ref() { if(--m_refs == 0) delete this; }
|
||||
refcount_t ref_count() { return m_refs; }
|
||||
|
||||
template<typename T> stdext::shared_object_ptr<T> static_self_cast() { return stdext::shared_object_ptr<T>(static_cast<T*>(this)); }
|
||||
template<typename T> stdext::shared_object_ptr<T> dynamic_self_cast() { return stdext::shared_object_ptr<T>(dynamic_cast<T*>(this)); }
|
||||
template<typename T> stdext::shared_object_ptr<T> const_self_cast() { return stdext::shared_object_ptr<T>(const_cast<T*>(this)); }
|
||||
|
||||
private:
|
||||
unsigned int m_refs;
|
||||
refcount_t m_refs;
|
||||
};
|
||||
|
||||
template<class T, typename... Args>
|
||||
boost::intrusive_ptr<T> make_shared_object(Args... args) { return boost::intrusive_ptr<T>(new T(args...)); }
|
||||
template<class T>
|
||||
class shared_object_ptr
|
||||
{
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
shared_object_ptr(): px(nullptr) { }
|
||||
shared_object_ptr(T* p, bool add_ref = true) : px(p) { if(px != nullptr && add_ref) this->add_ref(); }
|
||||
shared_object_ptr(shared_object_ptr const& rhs): px(rhs.px) { if(px != nullptr) add_ref(); }
|
||||
template<class U>
|
||||
shared_object_ptr(shared_object_ptr<U> const& rhs, typename std::is_convertible<U,T>::type* = nullptr) : px(rhs.get()) { if(px != nullptr) add_ref(); }
|
||||
~shared_object_ptr() { if(px != nullptr) dec_ref(); }
|
||||
|
||||
void reset() { shared_object_ptr().swap(*this); }
|
||||
void reset(T* rhs) { shared_object_ptr( rhs ).swap(*this); }
|
||||
void swap(shared_object_ptr& rhs) { std::swap(px, rhs.px); }
|
||||
T* get() const { return px; }
|
||||
|
||||
refcount_t use_count() const { return ((shared_object*)px)->ref_count(); }
|
||||
bool is_unique() const { return use_count() == 1; }
|
||||
|
||||
template<class U> shared_object_ptr& operator=(shared_object_ptr<U> const& rhs) { shared_object_ptr(rhs).swap(*this); return *this; }
|
||||
|
||||
T& operator*() const { assert(px != nullptr); return *px; }
|
||||
T* operator->() const { assert(px != nullptr); return px; }
|
||||
|
||||
shared_object_ptr& operator=(shared_object_ptr const& rhs) { shared_object_ptr(rhs).swap(*this); return *this; }
|
||||
shared_object_ptr& operator=(T* rhs) { shared_object_ptr(rhs).swap(*this); return *this; }
|
||||
|
||||
// implicit conversion to bool
|
||||
typedef T* shared_object_ptr::*unspecified_bool_type;
|
||||
operator unspecified_bool_type() const { return px == nullptr ? nullptr : &shared_object_ptr::px; }
|
||||
bool operator!() const { return px == nullptr; }
|
||||
|
||||
// std::move support
|
||||
shared_object_ptr(shared_object_ptr&& rhs): px(rhs.px) { rhs.px = nullptr; }
|
||||
shared_object_ptr& operator=(shared_object_ptr&& rhs) { shared_object_ptr(static_cast<shared_object_ptr&&>(rhs)).swap(*this); return *this; }
|
||||
|
||||
private:
|
||||
void add_ref() { ((shared_object*)px)->add_ref(); }
|
||||
void dec_ref() { ((shared_object*)px)->dec_ref(); }
|
||||
|
||||
T* px;
|
||||
};
|
||||
|
||||
template<class T, class U> bool operator==(shared_object_ptr<T> const& a, shared_object_ptr<U> const& b) { return a.get() == b.get(); }
|
||||
template<class T, class U> bool operator!=(shared_object_ptr<T> const& a, shared_object_ptr<U> const& b) { return a.get() != b.get(); }
|
||||
template<class T, class U> bool operator==(shared_object_ptr<T> const& a, U* b) { return a.get() == b; }
|
||||
template<class T, class U> bool operator!=(shared_object_ptr<T> const& a, U* b) { return a.get() != b; }
|
||||
template<class T, class U> bool operator==(T * a, shared_object_ptr<U> const& b) { return a == b.get(); }
|
||||
template<class T, class U> bool operator!=(T * a, shared_object_ptr<U> const& b) { return a != b.get(); }
|
||||
template<class T> bool operator<(shared_object_ptr<T> const& a, shared_object_ptr<T> const& b) { return std::less<T*>()(a.get(), b.get()); }
|
||||
|
||||
template<class T> T* get_pointer(shared_object_ptr<T> const& p) { return p.get(); }
|
||||
template<class T, class U> shared_object_ptr<T> static_pointer_cast(shared_object_ptr<U> const& p) { return static_cast<T*>(p.get()); }
|
||||
template<class T, class U> shared_object_ptr<T> const_pointer_cast(shared_object_ptr<U> const& p) { return const_cast<T*>(p.get()); }
|
||||
template<class T, class U> shared_object_ptr<T> dynamic_pointer_cast(shared_object_ptr<U> const& p) { return dynamic_cast<T*>(p.get()); }
|
||||
template<class T, typename... Args> stdext::shared_object_ptr<T> make_shared_object(Args... args) { return stdext::shared_object_ptr<T>(new T(args...)); }
|
||||
|
||||
// operator<< support
|
||||
template<class E, class T, class Y> std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& os, shared_object_ptr<Y> const& p) { os << p.get(); return os; }
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
struct hash<boost::intrusive_ptr<T>> : public __hash_base<size_t, boost::intrusive_ptr<T>> {
|
||||
size_t operator()(const boost::intrusive_ptr<T>& p) const noexcept { return std::hash<T*>()(p.get()); }
|
||||
};
|
||||
|
||||
// hash, for unordered_map support
|
||||
template<typename T> struct hash<stdext::shared_object_ptr<T>> { size_t operator()(const stdext::shared_object_ptr<T>& p) const { return std::hash<T*>()(p.get()); } };
|
||||
|
||||
// swap support
|
||||
template<class T> void swap(stdext::shared_object_ptr<T>& lhs, stdext::shared_object_ptr<T>& rhs) { lhs.swap(rhs); }
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct remove_const_ref {
|
||||
typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void intrusive_ptr_add_ref(T* p) { (static_cast<stdext::shared_object*>(p))->add_ref(); }
|
||||
|
||||
template<typename T>
|
||||
void intrusive_ptr_release(T* p) { (static_cast<stdext::shared_object*>(p))->dec_ref(); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -24,16 +24,21 @@
|
||||
#define STDEXT_H
|
||||
|
||||
#include "compiler.h"
|
||||
#include "dumper.h"
|
||||
#include "types.h"
|
||||
#include "exception.h"
|
||||
#include "demangle.h"
|
||||
#include "cast.h"
|
||||
#include "math.h"
|
||||
#include "string.h"
|
||||
#include "dumper.h"
|
||||
#include "time.h"
|
||||
#include "shared_object.h"
|
||||
#include "attrib_storage.h"
|
||||
#include "boolean.h"
|
||||
#include "shared_object.h"
|
||||
#include "any.h"
|
||||
#include "packed_any.h"
|
||||
#include "dynamic_storage.h"
|
||||
#include "packed_storage.h"
|
||||
#include "format.h"
|
||||
#include "packed_vector.h"
|
||||
|
||||
#endif
|
||||
|
||||
145
src/framework/stdext/string.cpp
Normal file
145
src/framework/stdext/string.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "format.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
std::string resolve_path(const std::string& filePath, std::string sourcePath)
|
||||
{
|
||||
if(stdext::starts_with(filePath, "/"))
|
||||
return filePath;
|
||||
if(!stdext::ends_with(sourcePath, "/")) {
|
||||
std::size_t slashPos = sourcePath.find_last_of("/");
|
||||
if(slashPos == std::string::npos)
|
||||
throw_exception(format("invalid source path '%s', for file '%s'", sourcePath, filePath));
|
||||
sourcePath = sourcePath.substr(0, slashPos + 1);
|
||||
}
|
||||
return sourcePath + filePath;
|
||||
}
|
||||
|
||||
std::string date_time_string()
|
||||
{
|
||||
char date[32];
|
||||
std::time_t tnow;
|
||||
std::time(&tnow);
|
||||
std::tm *ts = std::localtime(&tnow);
|
||||
std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts);
|
||||
return std::string(date);
|
||||
}
|
||||
|
||||
std::string dec_to_hex(uint64_t num)
|
||||
{
|
||||
std::string str;
|
||||
std::ostringstream o;
|
||||
o << std::hex << num;
|
||||
str = o.str();
|
||||
return str;
|
||||
}
|
||||
|
||||
uint64_t hex_to_dec(const std::string& str)
|
||||
{
|
||||
uint64_t num;
|
||||
std::istringstream i(str);
|
||||
i >> std::hex >> num;
|
||||
return num;
|
||||
}
|
||||
|
||||
std::string ip_to_string(uint32_t ip)
|
||||
{
|
||||
char host[16];
|
||||
sprintf(host, "%d.%d.%d.%d", (uint8_t)ip, (uint8_t)(ip >> 8), (uint8_t)(ip >> 16), (uint8_t)(ip >> 24));
|
||||
return std::string(host);
|
||||
}
|
||||
|
||||
std::string utf8_to_latin1(uchar *utf8)
|
||||
{
|
||||
auto utf8CharToLatin1 = [](uchar *utf8, int *read) -> char {
|
||||
char c = '?';
|
||||
uchar opt1 = utf8[0];
|
||||
*read = 1;
|
||||
if(opt1 == 0xc3) {
|
||||
*read = 2;
|
||||
uchar opt2 = utf8[1];
|
||||
c = 64 + opt2;
|
||||
} else if(opt1 == 0xc2) {
|
||||
*read = 2;
|
||||
uchar opt2 = utf8[1];
|
||||
if(opt2 > 0xa1 && opt2 < 0xbb)
|
||||
c = opt2;
|
||||
} else if(opt1 < 0xc2) {
|
||||
c = opt1;
|
||||
}
|
||||
return c;
|
||||
};
|
||||
|
||||
std::string out;
|
||||
int len = strlen((char*)utf8);
|
||||
for(int i=0; i<len;) {
|
||||
int read = 0;
|
||||
uchar *utf8char = &utf8[i];
|
||||
out += utf8CharToLatin1(utf8char, &read);
|
||||
i += read;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void tolower(std::string& str)
|
||||
{
|
||||
boost::to_lower(str);
|
||||
}
|
||||
|
||||
void toupper(std::string& str)
|
||||
{
|
||||
boost::to_upper(str);
|
||||
}
|
||||
|
||||
void trim(std::string& str)
|
||||
{
|
||||
boost::trim(str);
|
||||
}
|
||||
|
||||
bool ends_with(const std::string& str, const std::string& test)
|
||||
{
|
||||
return boost::ends_with(str, test);
|
||||
}
|
||||
|
||||
bool starts_with(const std::string& str, const std::string& test)
|
||||
{
|
||||
return boost::starts_with(str, test);
|
||||
}
|
||||
|
||||
void replace_all(std::string& str, const std::string& search, const std::string& replacement)
|
||||
{
|
||||
return boost::replace_all(str, search, replacement);
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string& str, const std::string& separators)
|
||||
{
|
||||
std::vector<std::string> splitted;
|
||||
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
|
||||
return splitted;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,234 +25,41 @@
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "types.h"
|
||||
#include "cast.h"
|
||||
#include "exception.h"
|
||||
|
||||
namespace stdext {
|
||||
|
||||
/// Convert any type to std::string
|
||||
template<typename T>
|
||||
std::string to_string(const T& t) { return unsafe_cast<std::string, T>(t); }
|
||||
template<typename T> std::string to_string(const T& t) { return unsafe_cast<std::string, T>(t); }
|
||||
template<typename T> T from_string(const std::string& str, T def = T()) { return unsafe_cast<T, std::string>(str, def); }
|
||||
|
||||
/// Convert any type from std::string
|
||||
template<typename T>
|
||||
T from_string(const std::string& str, T def = T()) { return unsafe_cast<T, std::string>(str, def); }
|
||||
/// Resolve a file path by combining sourcePath with filePath
|
||||
std::string resolve_path(const std::string& filePath, std::string sourcePath);
|
||||
/// Get current date and time in a std::string
|
||||
std::string date_time_string();
|
||||
|
||||
/// Cast non-class types like int, char, float, double and pointers
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_integral<T>::value ||
|
||||
std::is_pointer<T>::value ||
|
||||
std::is_floating_point<T>::value ||
|
||||
std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; }
|
||||
std::string dec_to_hex(uint64_t num);
|
||||
uint64_t hex_to_dec(const std::string& str);
|
||||
std::string ip_to_string(uint32_t ip);
|
||||
std::string utf8_to_latin1(uchar *utf8);
|
||||
void tolower(std::string& str);
|
||||
void toupper(std::string& str);
|
||||
void trim(std::string& str);
|
||||
bool ends_with(const std::string& str, const std::string& test);
|
||||
bool starts_with(const std::string& str, const std::string& test);
|
||||
void replace_all(std::string& str, const std::string& search, const std::string& replacement);
|
||||
|
||||
/// Cast std::string
|
||||
inline const char *sprintf_cast(const std::string& s) { return s.c_str(); }
|
||||
|
||||
template<int N>
|
||||
struct expand_snprintf{
|
||||
template<typename Tuple, typename... Args>
|
||||
static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
|
||||
return expand_snprintf<N-1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N-1>(tuple)), args...);
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct expand_snprintf<0> {
|
||||
template<typename Tuple, typename... Args>
|
||||
static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
|
||||
return snprintf(s, maxlen, format, args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct replace_extent { typedef T type; };
|
||||
|
||||
template<class T>
|
||||
struct replace_extent<T[]> { typedef const T* type; };
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct replace_extent<T[N]> { typedef const T* type;};
|
||||
|
||||
/// Improved sprintf that accepts std::string and other types
|
||||
template<typename... Args>
|
||||
int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) {
|
||||
typedef typename std::tuple<typename replace_extent<Args>::type...> Tuple;
|
||||
enum { N = std::tuple_size<Tuple>::value };
|
||||
Tuple tuple(args...);
|
||||
return expand_snprintf<N>::call(s, maxlen, format, tuple);
|
||||
}
|
||||
|
||||
/// Format strings with the sprintf style, accepting std::string and string convertible types for %s
|
||||
template<typename... Args>
|
||||
std::string format(const std::string& format, const Args&... args) {
|
||||
int n, size = 1024;
|
||||
std::string str;
|
||||
while(true) {
|
||||
str.resize(size);
|
||||
n = snprintf(&str[0], size, format.c_str(), args...);
|
||||
assert(n != -1);
|
||||
if(n < size) {
|
||||
str.resize(n);
|
||||
return str;
|
||||
}
|
||||
size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
inline void fill_ostream(std::ostringstream&) { }
|
||||
|
||||
/// Fills an ostream by concatenating args
|
||||
template<class T, class... Args>
|
||||
void fill_ostream(std::ostringstream& stream, const T& first, const Args&... rest) {
|
||||
stream << first;
|
||||
fill_ostream(stream, rest...);
|
||||
}
|
||||
|
||||
/// Makes a std::string by concatenating args
|
||||
template<class... T>
|
||||
std::string mkstr(const T&... args) {
|
||||
std::ostringstream buf;
|
||||
fill_ostream(buf, args...);
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
/// Easy of use split
|
||||
template<typename T = std::string>
|
||||
std::vector<T> split(const std::string& str, const std::string& separators = " ") {
|
||||
std::vector<std::string> splitted;
|
||||
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
|
||||
std::vector<std::string> split(const std::string& str, const std::string& separators = " ");
|
||||
template<typename T> std::vector<T> split(const std::string& str, const std::string& separators = " ") {
|
||||
std::vector<std::string> splitted = split(str, separators);
|
||||
std::vector<T> results(splitted.size());
|
||||
for(uint i=0;i<splitted.size();++i)
|
||||
results[i] = safe_cast<T>(splitted[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// Resolve a file path by combining sourcePath with filePath
|
||||
inline std::string resolve_path(const std::string& filePath, std::string sourcePath) {
|
||||
if(boost::starts_with(filePath, "/"))
|
||||
return filePath;
|
||||
if(!boost::ends_with(sourcePath, "/")) {
|
||||
std::size_t slashPos = sourcePath.find_last_of("/");
|
||||
if(slashPos == std::string::npos)
|
||||
throw_exception(format("invalid source path '%s', for file '%s'", sourcePath, filePath));
|
||||
sourcePath = sourcePath.substr(0, slashPos + 1);
|
||||
}
|
||||
return sourcePath + filePath;
|
||||
}
|
||||
|
||||
/// Get current date and time in a std::string
|
||||
inline std::string date_time_string() {
|
||||
char date[32];
|
||||
std::time_t tnow;
|
||||
std::time(&tnow);
|
||||
std::tm *ts = std::localtime(&tnow);
|
||||
std::strftime(date, 32, "%b %d %Y %H:%M:%S", ts);
|
||||
return std::string(date);
|
||||
}
|
||||
|
||||
/// Convert decimal to hexadecimal
|
||||
inline std::string dec_to_hex(uint64 num) {
|
||||
std::string str;
|
||||
std::ostringstream o;
|
||||
o << std::hex << num;
|
||||
str = o.str();
|
||||
return str;
|
||||
}
|
||||
|
||||
/// Convert hexadecimal to decimal
|
||||
inline uint64 hex_to_dec(const std::string& str) {
|
||||
uint64 num;
|
||||
std::istringstream i(str);
|
||||
i >> std::hex >> num;
|
||||
return num;
|
||||
}
|
||||
|
||||
/// Convert ip to string
|
||||
inline std::string ip_to_string(uint32 ip) {
|
||||
char host[16];
|
||||
sprintf(host, "%d.%d.%d.%d", (uint8)ip, (uint8)(ip >> 8), (uint8)(ip >> 16), (uint8)(ip >> 24));
|
||||
return std::string(host);
|
||||
}
|
||||
|
||||
/// Convert utf8 characters to latin1
|
||||
inline char utf8CharToLatin1(uchar *utf8, int *read) {
|
||||
char c = '?';
|
||||
uchar opt1 = utf8[0];
|
||||
*read = 1;
|
||||
if(opt1 == 0xc3) {
|
||||
*read = 2;
|
||||
uchar opt2 = utf8[1];
|
||||
c = 64 + opt2;
|
||||
} else if(opt1 == 0xc2) {
|
||||
*read = 2;
|
||||
uchar opt2 = utf8[1];
|
||||
if(opt2 > 0xa1 && opt2 < 0xbb)
|
||||
c = opt2;
|
||||
} else if(opt1 < 0xc2) {
|
||||
c = opt1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/// Convert utf8 strings to latin1
|
||||
inline std::string utf8StringToLatin1(uchar *utf8) {
|
||||
std::string out;
|
||||
int len = strlen((char*)utf8);
|
||||
for(int i=0; i<len;) {
|
||||
int read = 0;
|
||||
uchar *utf8char = &utf8[i];
|
||||
out += utf8CharToLatin1(utf8char, &read);
|
||||
i += read;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Convert string to lower case
|
||||
inline std::string tolower(const std::string& str)
|
||||
{
|
||||
std::string cpy = str;
|
||||
boost::algorithm::to_lower(cpy);
|
||||
return cpy;
|
||||
}
|
||||
|
||||
// Convert string to upper case
|
||||
inline std::string toupper(const std::string& str)
|
||||
{
|
||||
std::string cpy = str;
|
||||
boost::algorithm::to_upper(cpy);
|
||||
return cpy;
|
||||
}
|
||||
|
||||
// Trim string
|
||||
inline std::string trim(const std::string& str)
|
||||
{
|
||||
std::string cpy = str;
|
||||
boost::algorithm::trim(cpy);
|
||||
return cpy;
|
||||
}
|
||||
|
||||
// utility for printing messages into stdout
|
||||
template<class... T>
|
||||
void print(const T&... args) {
|
||||
std::ostringstream buf;
|
||||
fill_ostream(buf, args...);
|
||||
std::cout << buf.str();
|
||||
}
|
||||
|
||||
template<class... T>
|
||||
void println(const T&... args) {
|
||||
print(args...);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "cast.h"
|
||||
|
||||
#endif
|
||||
|
||||
49
src/framework/stdext/time.cpp
Normal file
49
src/framework/stdext/time.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "time.h"
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
const static auto startup_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
ticks_t millis()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - startup_time).count();
|
||||
}
|
||||
ticks_t micros() {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - startup_time).count();
|
||||
}
|
||||
|
||||
void millisleep(size_t ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
};
|
||||
|
||||
void microsleep(size_t us)
|
||||
{
|
||||
usleep(us);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -24,16 +24,13 @@
|
||||
#define STDEXT_TIME_H
|
||||
|
||||
#include "types.h"
|
||||
#include <chrono>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
const static auto startup_time = std::chrono::high_resolution_clock::now();
|
||||
inline ticks_t millis() { return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - startup_time).count(); }
|
||||
inline ticks_t micros() { return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - startup_time).count(); }
|
||||
inline void millisleep(uint32 ms) { usleep(ms * 1000); };
|
||||
inline void microsleep(uint32 us) { usleep(us); };
|
||||
ticks_t millis();
|
||||
ticks_t micros();
|
||||
void millisleep(size_t ms);
|
||||
void microsleep(size_t us);
|
||||
|
||||
struct timer {
|
||||
public:
|
||||
|
||||
37
src/framework/stdext/traits.h
Normal file
37
src/framework/stdext/traits.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/otclient>
|
||||
*
|
||||
* 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 STDEXT_TRAITS_H
|
||||
#define STDEXT_TRAITS_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace stdext {
|
||||
|
||||
template<class T> struct replace_extent { typedef T type; };
|
||||
template<class T> struct replace_extent<T[]> { typedef const T* type; };
|
||||
template<class T, unsigned long N> struct replace_extent<T[N]> { typedef const T* type;};
|
||||
template<typename T> struct remove_const_ref { typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type; };
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -23,13 +23,13 @@
|
||||
#ifndef STDEXT_TYPES_H
|
||||
#define STDEXT_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
|
||||
// easy handwriting types
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
@@ -39,19 +39,9 @@ typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
|
||||
typedef unsigned char fast_uchar;
|
||||
typedef unsigned long fast_ushort;
|
||||
typedef unsigned long fast_uint;
|
||||
typedef unsigned long fast_ulong;
|
||||
typedef uint_fast64_t fast_uint64;
|
||||
typedef uint_fast32_t fast_uint32;
|
||||
typedef uint_fast16_t fast_uint16;
|
||||
typedef uint_fast8_t fast_uint8;
|
||||
typedef int_fast64_t fast_int64;
|
||||
typedef int_fast32_t fast_int32;
|
||||
typedef int_fast16_t fast_int16;
|
||||
typedef int_fast8_t fast_int8;
|
||||
typedef int64 ticks_t;
|
||||
|
||||
typedef int64_t ticks_t;
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user