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:
Eduardo Bart
2012-08-01 04:49:09 -03:00
parent 1dc7dc0cfc
commit 3bac3dcbb4
92 changed files with 1885 additions and 1208 deletions

View 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

View File

@@ -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

View File

@@ -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."

View 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;
}
}

View File

@@ -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()); }
}

View File

@@ -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;
}

View 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

View File

@@ -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;
};

View 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

View 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);
}
}

View File

@@ -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);
}

View 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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View 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;
}
}

View File

@@ -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

View 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);
};
}

View File

@@ -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:

View 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

View File

@@ -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