Alien-libpanda
view release on metacpan or search on metacpan
1.2.3 22.07.2019
- move fake std::string_view to panda::string_view + related changes
- fix endian.h for C++17 clang (fuck macros)
- fix intrusive_chain compilation for clang17
- fix compilation warnings for clang17
- return #include <ostream> to log.h (unfortunately, but there is no workaround)
- remove panda::lib/traits/etc namespace, accumulate all utils in panda::
1.2.2 15.07.2019
- fix compiler warnings
1.2.1 12.07.2019
- add get_global_[tls_]ptr
- add PANDA_GLOBAL/TLS_MEMBER[_PTR] macros helpers for creating static members
(global or tls) which has the same address across any shared library.
- change log level names to camel case (fuck the fucking macros)
- fix intrusive_chain size(): now O(1)
- CallbackDispatcher: extended callback is now accepted only in add_event_listener
to resolve ambiguity with template lambdas when dispatcher.add([](auto...) { });
1.2.0 25.06.2019
- add panda::excepted (expected with strict error checking and exception propagation)
- add panda::expected (P0323R7)
- add string_view compare operators with const C*
- removed panda::shared_ptr, panda::Refcounted (use panda::Refcnt instead)
- iptr now uses refcnt_inc/dec/get proxies
src/panda/memory.cc view on Meta::CPAN
#include "memory.h"
#include "string.h"
#include <map>
#include <mutex>
#include <string.h>
namespace panda {
static std::map<string, void*> global_ptrs;
static std::mutex global_ptrs_mutex;
static thread_local std::map<string, void*> global_tls_ptrs;
static const int START_SIZE = 16;
DynamicMemoryPool* DynamicMemoryPool::_global_instance = new DynamicMemoryPool();
void* detail::__get_global_ptr (const std::type_info& ti, const char* name, void* val) {
string key(ti.name());
if (name) key += name;
std::lock_guard<std::mutex> guard(global_ptrs_mutex);
auto it = global_ptrs.find(key);
if (it != global_ptrs.end()) return it->second;
global_ptrs.emplace(key, val);
return val;
}
void* detail::__get_global_tls_ptr (const std::type_info& ti, const char* name, void* val) {
string key(ti.name());
if (name) key += name;
auto it = global_tls_ptrs.find(key);
if (it != global_tls_ptrs.end()) return it->second;
global_tls_ptrs.emplace(key, val);
return val;
}
void MemoryPool::grow () {
size_t pools_cnt = pools.size();
if (pools_cnt) {
pools.resize(pools_cnt+1);
pools[pools_cnt].size = pools[pools_cnt-1].size*2;
} else {
pools.resize(1);
src/panda/memory.h view on Meta::CPAN
#pragma once
#include <vector>
#include <memory>
#include <assert.h>
#include <stdexcept>
namespace panda {
namespace detail {
void* __get_global_ptr (const std::type_info& ti, const char* name, void* val);
void* __get_global_tls_ptr (const std::type_info& ti, const char* name, void* val);
}
template <class CLASS, class T>
inline T* get_global_ptr (T* val, const char* name = NULL) {
return reinterpret_cast<T*>(detail::__get_global_ptr(typeid(CLASS), name, reinterpret_cast<void*>(val)));
}
template <class CLASS, class T>
inline T* get_global_tls_ptr (T* val, const char* name = NULL) {
return reinterpret_cast<T*>(detail::__get_global_tls_ptr(typeid(CLASS), name, reinterpret_cast<void*>(val)));
}
#define PANDA_GLOBAL_MEMBER_PTR(CLASS, TYPE, accessor, defval) \
static TYPE accessor () { \
static TYPE ptr; \
if (!ptr) ptr = panda::get_global_ptr<CLASS>(defval, #accessor); \
return ptr; \
}
#define PANDA_GLOBAL_MEMBER(CLASS, TYPE, accessor, defval) \
static TYPE& accessor () { \
static TYPE* ptr; \
if (!ptr) { \
static TYPE val = defval; \
ptr = panda::get_global_ptr<CLASS>(&val, #accessor); \
} \
return *ptr; \
}
#define PANDA_GLOBAL_MEMBER_AS_PTR(CLASS, TYPE, accessor, defval) \
static TYPE* accessor () { \
static TYPE* ptr; \
if (!ptr) { \
static TYPE val = defval; \
ptr = panda::get_global_ptr<CLASS>(&val, #accessor); \
} \
return ptr; \
}
#define PANDA_TLS_MEMBER_PTR(CLASS, TYPE, accessor, defval) \
static TYPE accessor () { \
static thread_local TYPE _ptr; \
TYPE ptr = _ptr; \
if (!ptr) ptr = _ptr = panda::get_global_tls_ptr<CLASS>(defval, #accessor); \
return ptr; \
}
#define PANDA_TLS_MEMBER(CLASS, TYPE, accessor, defval) \
static TYPE& accessor () { \
static thread_local TYPE* _ptr; \
TYPE* ptr = _ptr; \
if (!ptr) { \
static thread_local TYPE val = defval; \
ptr = _ptr = panda::get_global_tls_ptr<CLASS>(&val, #accessor); \
} \
return *ptr; \
}
#define PANDA_TLS_MEMBER_AS_PTR(CLASS, TYPE, accessor, defval) \
static TYPE* accessor () { \
static thread_local TYPE* _ptr; \
TYPE* ptr = _ptr; \
if (!ptr) { \
static thread_local TYPE val = defval; \
ptr = _ptr = panda::get_global_tls_ptr<CLASS>(&val, #accessor); \
} \
return ptr; \
}
struct MemoryPool {
MemoryPool (size_t blocksize) : first_free(NULL) {
this->blocksize = round_up(blocksize);
}
void* allocate () {
src/panda/memory.h view on Meta::CPAN
const size_t factor = sizeof(void*);
if ((size & (factor-1)) == 0) return size;
size += factor;
size &= ~((size_t)(factor-1));
return size;
}
};
template <int BLOCKSIZE>
struct StaticMemoryPool {
PANDA_GLOBAL_MEMBER_PTR(StaticMemoryPool, MemoryPool*, global_instance, new MemoryPool(BLOCKSIZE));
PANDA_TLS_MEMBER_PTR (StaticMemoryPool, MemoryPool*, instance, new MemoryPool(BLOCKSIZE));
static void* allocate () { return instance()->allocate(); }
static void deallocate (void* p) { instance()->deallocate(p); }
};
template <> struct StaticMemoryPool<7> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<6> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<5> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<4> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<3> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<2> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<1> : StaticMemoryPool<8> {};
struct DynamicMemoryPool {
static DynamicMemoryPool* global_instance () { return _global_instance; }
PANDA_TLS_MEMBER_PTR(DynamicMemoryPool, DynamicMemoryPool*, instance, new DynamicMemoryPool());
DynamicMemoryPool ();
void* allocate (size_t size) {
if (size == 0) return NULL;
MemoryPool* pool;
if (size <= 1024) {
pool = small_pools[(size-1)>>2];
src/panda/memory.h view on Meta::CPAN
else if (size <= 16384) pool = medium_pools[(size-1)>>6];
else if (size <= 262144) pool = big_pools[(size-1)>>10];
else throw std::invalid_argument("ObjectAllocator: object size cannot exceed 256k");
pool->deallocate(ptr);
}
~DynamicMemoryPool ();
private:
static constexpr const int POOLS_CNT = 256;
static DynamicMemoryPool* _global_instance;
MemoryPool* small_pools[POOLS_CNT];
MemoryPool* medium_pools[POOLS_CNT];
MemoryPool* big_pools[POOLS_CNT];
};
template <class TARGET, bool THREAD_SAFE = true>
struct AllocatedObject {
static void* operator new (size_t, void* p) { return p; }
src/panda/memory.h view on Meta::CPAN
if (size == sizeof(TARGET)) StaticMemoryPool<sizeof(TARGET)>::deallocate(p);
else DynamicMemoryPool::instance()->deallocate(p, size);
}
};
template <class TARGET>
struct AllocatedObject<TARGET, false> {
static void* operator new (size_t, void* p) { return p; }
static void* operator new (size_t size) {
if (size == sizeof(TARGET)) return StaticMemoryPool<sizeof(TARGET)>::global_instance()->allocate();
else return DynamicMemoryPool::global_instance()->allocate(size);
}
static void operator delete (void* p, size_t size) {
if (size == sizeof(TARGET)) StaticMemoryPool<sizeof(TARGET)>::global_instance()->deallocate(p);
else DynamicMemoryPool::global_instance()->deallocate(p, size);
}
};
}
t/string_test.h view on Meta::CPAN
auto e = s.end();
REQUIRE(b >= b);
REQUIRE(!(b > b));
REQUIRE(e > b);
REQUIRE(b < e);
REQUIRE(b <= e);
REQUIRE(e <= e);
REQUIRE(!(e < e ));
}
SECTION("global -+ operators") {
auto b = s.begin();
auto e = s.end();
REQUIRE(*(b + 1) == (T)'1');
REQUIRE(*(2 + b) == (T)'2');
REQUIRE(*(e - 1) == (T)'9');
REQUIRE(*(2 - e) == (T)'8');
}
SECTION("as const iterator") {
( run in 0.603 second using v1.01-cache-2.11-cpan-49f99fa48dc )