Code Monkey home page Code Monkey logo

memory's Introduction

memory

Project Status Build Status Code Coverage

The C++ STL allocator model has various flaws. For example, they are fixed to a certain type, because they are almost necessarily required to be templates. So you can't easily share a single allocator for multiple types. In addition, you can only get a copy from the containers and not the original allocator object. At least with C++11 they are allowed to be stateful and so can be made object not instance based. But still, the model has many flaws. Over the course of the years many solutions have been proposed, for example EASTL. This library is another. But instead of trying to change the STL, it works with the current implementation.

Features

New allocator concepts:

  • a RawAllocator that is similar to an Allocator but easier to use and write
  • a BlockAllocator that is an allocator for huge memory blocks

Several implementations:

  • heap_/malloc_/new_allocator
  • virtual memory allocators
  • allocator using a static memory block located on the stack
  • memory stack, iteration_allocator
  • different memory pools
  • a portable, improved alloca() in the form of temporary_allocator
  • facilities for joint memory allocations: share a big memory block for the object and all dynamic memory allocations for its members

Adapters, wrappers and storage classes:

  • incredible powerful allocator_traits allowing Allocators as RawAllocators
  • std_allocator to make a RawAllocator an Allocator again
  • adapters for the memory resource TS
  • allocator_deleter classes for smart pointers
  • (optionally type-erased) allocator_reference and other storage classes
  • memory tracking wrapper

In addition:

  • container node size debuggers that obtain information about the node size of an STL container at compile-time to specify node sizes for pools
  • debugging options for leak checking, double-free checks or buffer overflows
  • customizable error handling routines that can work with exceptions disabled
  • everything except the STL adapters works on a freestanding environment

Basic example

#include <algorithm>
#include <iostream>
#include <iterator>

#include <foonathan/memory/container.hpp> // vector, list, list_node_size
#include <foonathan/memory/memory_pool.hpp> // memory_pool
#include <foonathan/memory/smart_ptr.hpp> // allocate_unique
#include <foonathan/memory/static_allocator.hpp> // static_allocator_storage, static_block_allocator
#include <foonathan/memory/temporary_allocator.hpp> // temporary_allocator

// alias namespace foonathan::memory as memory for easier access
#include <foonathan/memory/namespace_alias.hpp>

template <typename BiIter>
void merge_sort(BiIter begin, BiIter end);

int main()
{
    using namespace memory::literals;

    // a memory pool RawAllocator
    // allocates a memory block - initially 4KiB - and splits it into chunks of list_node_size<int>::value big
    // list_node_size<int>::value is the size of each node of a std::list
    memory::memory_pool<> pool(memory::list_node_size<int>::value, 4_KiB);

    // just an alias for std::list<int, memory::std_allocator<int, memory::memory_pool<>>
    // a std::list using a memory_pool
    // std_allocator stores a reference to a RawAllocator and provides the Allocator interface
    memory::list<int, memory::memory_pool<>> list(pool);
    list.push_back(3);
    list.push_back(2);
    list.push_back(1);

    for (auto e : list)
        std::cout << e << ' ';
    std::cout << '\n';

    merge_sort(list.begin(), list.end());

    for (auto e : list)
        std::cout << e << ' ';
    std::cout << '\n';

    // allocate a std::unique_ptr using the pool
    // memory::allocate_shared is also available
    auto ptr = memory::allocate_unique<int>(pool, *list.begin());
    std::cout << *ptr << '\n';

    // static storage of size 4KiB
    memory::static_allocator_storage<4096u> storage;

    // a memory pool again but this time with a BlockAllocator
    // this controls the internal allocations of the pool itself
    // we need to specify the first template parameter giving the type of the pool as well
    // (node_pool is the default)
    // we use a static_block_allocator that uses the static storage above
    // all allocations will use a memory block on the stack
    using static_pool_t = memory::memory_pool<memory::node_pool, memory::static_block_allocator>;
    static_pool_t static_pool(memory::unordered_set_node_size<int>::value, 4096u, storage);

    // again, just an alias for std::unordered_set<int, std::hash<int>, std::equal_to<int>, memory::std_allocator<int, static_pool_t>
    // see why I wrote these? :D
    // now we have a hash set that lives on the stack!
    memory::unordered_set<int, static_pool_t> set(static_pool);

    set.insert(3);
    set.insert(2);
    set.insert(3); // running out of stack memory is properly handled, of course

    for (auto e : set)
        std::cout << e << ' ';
    std::cout << '\n';
}

// naive implementation of merge_sort using temporary memory allocator
template <typename BiIter>
void merge_sort(BiIter begin, BiIter end)
{
    using value_type = typename std::iterator_traits<BiIter>::value_type;

    auto distance = std::distance(begin, end);
    if (distance <= 1)
        return;

    auto mid = begin;
    std::advance(mid, distance / 2);

    // an allocator for temporary memory
    // is similar to alloca() but uses its own stack
    // this stack is thread_local and created on the first call to this function
    // as soon as the allocator object goes out of scope, everything allocated through it, will be freed
    auto alloc = memory::temporary_allocator();

    // alias for std::vector<value_type, memory::std_allocator<value_type, memory::temporary_allocator>>
    // a std::vector using a temporary_allocator
    memory::vector<value_type, memory::temporary_allocator> first(begin, mid, alloc),
                                                            second(mid, end, alloc);

    merge_sort(first.begin(), first.end());
    merge_sort(second.begin(), second.end());
    std::merge(first.begin(), first.end(), second.begin(), second.end(), begin);
}

See example/ for more.

Installation

This library can be used as CMake subdirectory. It is tested on GCC 4.8-5.0, Clang 3.5 and Visual Studio 2013. Newer versions should work too.

  1. Fetch it, e.g. using git submodules git submodule add https://github.com/foonathan/memory ext/memory and git submodule update --init --recursive.

  2. Call add_subdirectory(ext/memory) or whatever your local path is to make it available in CMake.

  3. Simply call target_link_libraries(your_target PUBLIC foonathan_memory) to link this library and setups the include search path and compilation options.

You can also install the library:

  1. Run cmake -DCMAKE_BUILD_TYPE="buildtype" -DFOONATHAN_MEMORY_BUILD_EXAMPLES=OFF -DFOONATHAN_MEMORY_BUILD_TESTS=OFF . inside the library sources.

  2. Run cmake --build . -- install to install the library under ${CMAKE_INSTALL_PREFIX}.

  3. Repeat 1 and 2 for each build type/configuration you want to have (like Debug, RelWithDebInfo and Release or custom names).

To use an installed library:

  1. Call find_package(foonathan_memory major.minor REQUIRED) to find the library.

  2. Call target_link_libraries(your_target PUBLIC foonathan_memory) to link to the library and setup all required options.

See https://memory.foonathan.net/md_doc_installation.html for a detailed guide.

Building foonathan-memory - Using vcpkg

You can download and install foonathan-memory using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install foonathan-memory

The foonathan-memory port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Documentation

Full documentation can be found at https://memory.foonathan.net/.

A tutorial is also available at https://memory.foonathan.net/md_doc_tutorial.html.

RawAllocator

Below is the interface required for a RawAllocator, everything optional is marked:

struct raw_allocator
{
    using is_stateful = std::integral_constant<bool, Value>; // optional, defaults to std::is_empty

    void* allocate_node(std::size_t size, std::size_t alignment); // required, allocation function
    void deallocate_node(void *node, std::size_t size, std::size_t alignment) noexcept; // required, deallocation function

    void* allocate_array(std::size_t count, std::size_t size, std::size_t alignment); // optional, forwards to node version
    void deallocate_array(void *ptr, std::size_t count, std::size_t size, std::size_t alignment) noexcept; // optional, forwards to node version

    std::size_t max_node_size() const; // optional, returns maximum value
    std::size_t max_array_size() const; // optional, forwards to max_node_size()
    std::size_t max_alignment() const; // optional, returns maximum fundamental alignment, i.e. alignof(std::max_align_t)
};

A RawAllocator only needs to be moveable, all Allocator classes are RawAllocators too. Classes not providing the interface can specialize the allocator_traits, read more about writing allocators here or about the technical details of the concept here.

Acknowledgements

This project is greatly supported by my patrons. In particular thanks to the individual supporters:

  • Kaido Kert

And big thanks to the contributors as well:

  • @Guekka
  • @Manu343726
  • @MiguelCompany
  • @asobhy-qnx
  • @bfierz
  • @cho3
  • @gabyx
  • @j-carl
  • @kaidokert
  • @maksqwe
  • @moazzamak
  • @myd7349
  • @nicolastagliani
  • @quattrinili
  • @razr
  • @roehling
  • @seanyen
  • @wtsnyder
  • @zhouchengming1
  • @jwdevel

memory's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memory's Issues

fixed_block_allocator block_size

When allocating from a memory_stack using a fixed_block_allocator in debug mode , I have noticed that the effective size of the memory_stack on my machine is 24 bytes smaller than the requested block size. I have determined that 16 bytes are used by a fence; if I understand correctly, the remaining 8 bytes are used by the node of the intrusive list linking the blocks.

My questions are:

  1. How can I query the exact size of the overhead per block? I now fell back to to adding 32-bytes of slack.
  2. Although 8 wasted bytes is not a big deal for me, is it conceptually speaking necessary to keep the node around when the block is allocated?

Question: allocator for varying-length arrays?

I have been looking through the documented allocators, but have not found this:

Is there an allocator in this library meant for allocating lots of varying-sized arrays of nodes?

In my case, I want to allocate a lot of small spans of memory from my own storage, each span containing perhaps 1 to 100 nodes (each span must be contiguous).

I know there are approaches like buddy memory, but is there anything like that in this library?

Document the license type

I know it's Zlib because I asked you privately, but it's not obvious and I think it would avoid deterring someone from using the library.

Creating std::scoped_memory_adapter aliases

Currently the allocator aliases such as memory::unordered_map use directly memory::std_allocator<>.

However, if one wants to nest unordered_maps for example, using the rather intuitive memory::unordered_map<K1, memory::unordered_map<K2, V2>> leads to headaches since the [] operator requires the default constructor for the K2, V2 map to be called, which can't happen since we need to provide the allocator during creation.

Inside my code I've fixed this ('I've duplicated too much code' in this case) using the following std::scoped_allocator_adapter:

using memory_pool_collection = memory::memory_pool_collection<
		memory::node_pool,
		memory::log2_buckets>;

using unordered_set_int = std::unordered_set<int, std::hash<int>, std::equal_to<>,
		memory::std_allocator<int, memory_pool_collection, memory::default_mutex>>;

using unordered_map_int_si = std::unordered_map<int, unordered_set_int, std::hash<int>, std::equal_to<int>,
		std::scoped_allocator_adaptor<
				memory::std_allocator<std::pair<const int, unordered_set_int>, memory_pool_collection, memory::default_mutex>>>;

My proposal is that inside the container aliases header we could add something like

template <typename Key, typename Value, class RawAllocator, class Mutex = default_mutex>
FOONATHAN_ALIAS_TEMPLATE(
    unordered_map_scoped,
    std::unordered_map<Key, Value, std::hash<Key>, std::equal_to<Key>,
                       std::scoped_allocator_adapter<std_allocator<std::pair<const Key, Value>, RawAllocator, Mutex>>>);

This way the outermost allocator could be a scoped one, while the inside ones would still keep on being the normal versions. What I'm not entirely sure for now is if nesting 3 containers (so, map, in a map, in a map), requires the second container to be scoped or not.

Shared pointer usage from multiple threads

Hi,

Could you please take a look at the problem I am facing whenever you get time and help me if possible.

As I understand the memory pool is not protected by default and it should be protected if shared (ideally thread local). I am running into an issue where the library API needs to allocate memory and the API can be called from any number of threads so I can't guarantee thread local memory pool.
I get around the issue by protecting the allocation from pool using mutex. However, this still doesn't protect the deallocation. So code like this causes issue,

        {
            usleep(100); 
            allocMutex.lock();
            std::shared_ptr<TestSharedPointer> ptr1 = memory::allocate_shared<TestSharedPointer>(p, 10);  // Assume this allocate_shared is called from within API
            allocMutex.unlock();
            EXPECT_EQ(ptr1->getA(), 10);
        }

which is fixed, if I move the mutex out of scope thereby protecting deallocation.

      allocMutex.lock();
     {
          usleep(100); 
          std::shared_ptr<TestSharedPointer> ptr1 = memory::allocate_shared<TestSharedPointer>(p, 10);
          EXPECT_EQ(ptr1->getA(), 10);
      }
      allocMutex.unlock();

However, such a solution is not possible since as an API developer I don't have control over the life span of allocated pointer.
Am I missing something here? Is this use case not supported?

Conan package

Hello,
Do you know about Conan?
Conan is modern dependency manager for C++. And will be great if your library will be available via package manager for other developers.

Here you can find example, how you can create package for the library.

Also would be perfect, if you will create conan recipes for other your libraries.

If you have any questions, just ask :-)

`allocator_delete` does not support polymorphism

Cannot convert
std::unique_ptr<Game::KillShip, foonathan::memory::allocator_deleter<Game::KillShip, foonathan::memory::temporary_allocator, std::mutex>>
TO
std::unique_ptr<Game::EntityCommand, foonathan::memory::allocator_deleter<Game::EntityCommand, foonathan::memory::temporary_allocator, std::mutex>

where Game::EntityCommand is the base class of Game::KillShip

which pool to use for dynamic sizes

Is it possible to have a memory collection (log2 buckets) which has no maxnode size?
I have to following scenario, I receive binary message and I would like to have memory pool which provides me a char buffer for this binary messages. However I have no idea about the maximum size of the message. It can be that they are always below lets say 16kb and suddenly a message needs a buffer of 4mb. Can that be done with your pool collection?
Probably I misunderstand something here:

From the tests I see:

memory_pool_collection<node_pool, identity_buckets, allocator_reference<test_allocator>>;
    test_allocator alloc;
    {
        const auto max_size = 16u;
        pools      pool(max_size, 1000, alloc);

meaning we have a block size of 1000bytes and the maximum node size (my buffer size) is fixed to 16bytes... So when I request 17bytes what happens?

Thanks a lot =)

Gradle cmake issue

I have multiplatform library (Windows/Android/IOS/Linux) and I try to integrate and test your great library to all this projects. I have cmake project so integration to project files is pretty simple. Windows works very well after yesterday commit (thanks again). It is possible compile your library with android NDK? I have problem with this cmake step:
`

generate container_node_sizes.hpp

if(FOONATHAN_MEMORY_BUILD_TOOLS AND (NOT CMAKE_CROSS_COMPILING))
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/container_node_sizes_impl.hpp
COMMAND foonathan_memory_node_size_debugger --code --alignof "FOONATHAN_ALIGNOF(T)" ${CMAKE_CURRENT_BINARY_DIR}/container_node_sizes_impl.hpp
DEPENDS foonathan_memory_node_size_debugger
VERBATIM)
else()
message(WARNING "cannot generate container_node_sizes_impl.hpp, node size information will be unavailable")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/container_node_sizes_impl.hpp "")
endif()
`
I obtained following error in gradle build:
foonathan_memory_node_size_debugger --code --alignof FOONATHAN_ALIGNOF(T) C:/.../cmake/fullRelease/arm64-v8a/SDK/Library/Headers/Library/Memory/3rdParty/src/container_node_sizes_impl.hpp"
'foonathan_memory_node_size_debugger' is not recognized as an internal or external command,
operable program or batch file.
ninja: build stopped: subcommand failed.

I understand why it is a problem but exist any way to use it with android ndk and build application?

CMake install missing header ebo_storage.hpp

After building and installing x86-debug, I am missing the header ebo_storage.hpp in the detail directory of the installation path. It is perhaps also missing in the other build targets.
As a workaround I added the include folder in the root of the repository to the include path.

New release

Any reason that there hasn't been any release since October 2017? There seems to be useful improvements committed.

trouble with unordered_map and stateful allocators

Hi,

I'm having trouble compiling an unordered_map with a custom stateful raw allocator. I'm on OSX 12.10.6 with clang:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Here's a small sample program to demonstrate the problem:

#include <cstdio>
#include <cstdlib>
#include <foonathan/memory/container.hpp>

namespace my
{
    struct raw_stat_mallocator
    {
        using is_stateful = std::integral_constant<bool, true>; 

        size_t total;
        size_t current;

        void* allocate_node(std::size_t size, std::size_t alignment)
        {
            printf("[ %p ] Allocating %zd bytes (%zd total, %zd current)\n", this, size, total, current);
            total += size;
            current += size;
            return malloc(size);
        }

        void deallocate_node(void *node, std::size_t size, std::size_t alignment) noexcept
        {
            printf("[ %p ] Deallocating %zd bytes (%zd total, %zd current)\n", this, size, total, current); 
            current -= size;
            free(node);
        }
    };  

    using string = foonathan::memory::string<my::raw_stat_mallocator>;

    template<typename K, typename V>
    using hash_map = foonathan::memory::unordered_map<K, V, my::raw_stat_mallocator>;
}


int main()
{
    auto ral = my::raw_stat_mallocator();
    auto m1 = my::hash_map<int, my::string>(ral);
    auto m2 = my::hash_map<my::string, int>(ral);

    m1[2] = my::string("hello", ral);  // does not compile
    (void)m1[2]; // does not compile either
    m2[my::string("world", ral)] = 5; // this works however
    return EXIT_SUCCESS;
}

It looks like std::unordered_map does not propagate the allocator to the construction of the V when constructing std::pair<K,V>. It seems to work for the K though which is weird. Am I doing something wrong? Can I somehow provide the allocator explicitly when accessing the map? Maybe it's a problem with clang's particular implementation of the std::unordered_map? Do you have any idea of how to fix/work around this?

Thanks!

-Cédric

Failed to configure tools using emscripten

When configuring for emscripten the cmake command returns the following error:

cmake: /build/cmake-yjJ9_1/cmake-3.7.2/Source/cmOutputConverter.cxx:93: std::__cxx11::string cmOutputConverter::ConvertToRelativePath(const string&, const string&) const: Assertion `remote_path[0] != '\"'' failed.
ERROR:root:Configure step failed with non-zero return code: -6.  Command line: cmake -DCMAKE_CROSSCOMPILING_EMULATOR="/home/lrai/emsdk/node/8.9.1_64bit/bin/node" . -DCMAKE_TOOLCHAIN_FILE=/home/lrai/emsdk/emscripten/1.38.12/cmake/Modules/Platform/Emscripten.cmake at /mnt/c/Users/loren/Documents/Dev/Lib/foonathan/memory/build/emscripten

The configuration and building works when i set FOONATHAN_MEMORY_BUILD_TOOLS to OFF.
The entire build also works using msvc compilers so i assume my local copy isnt the problem.

As far as i can tell the tools are responsible for filling in the container_node_sizes_impl.hpp file, which my compiler tells me i do need.
Would it be difficult copy paste and adapt this file from one generated with native compilers?

iteration_allocator issues

This might be me, but when exiting a unit test in my project I get the line:
[foonathan::memory] Allocator foonathan::memory::heap_allocator (at 0000000000000000) leaked 16777248 bytes.

Indeed, I use an iteration_allocator which allocates 16M for the "initial block" using the default_allocator, which is the heap_allocator on my system. I cannot discover where this initial block is supposed to be released, since neither iteration_allocator nor fixed_block_allocator has a user-defined destructor?

Moreover, in release build the unit tests hangs at the very end unless I forcefully terminate with exit(.); might be unrelated though.

static assertion while using thread safe allocator

Hi,

I am running into an issue while using the thread safe allocator, could you take a look and help me find out what I am missing when you get time. Thanks!

This is my code using thread safe allocator

    memory::memory_pool<> pool(128, 1024);
    auto safe_pool = memory::make_thread_safe_allocator<std::mutex, memory::memory_pool<>>(std::move(pool));
    std::shared_ptr<int> p = memory::allocate_shared<int>(safe_pool, 10);

When I compile it, I get static assertion in file allocator_storage.cpp:111

            static_assert(
                !detail::is_nested_policy<StoragePolicy>::value,
                "allocator_storage instantiated with another allocator_storage, double wrapping!");

assertion in memory_pool_collection

using namespace literals;
using Poolocator = memory_pool_collection<node_pool, identity_buckets>;
Poolocator alloc(1000_MiB, 4000_MiB);

Why am I not able to allocate this memory_pool_collection.
Should'nt be the maximal node size 1Gb (meaning I can only allocat object of this maximal size) and the total managed memory block 4Gb
(I have enought ram, its not). It outputs the following on construction. What am I doing wrong?

[foonathan::memory] Assertion failure in function free_list_array (.../foonathan/memory/detail/free_list_array.hpp:41): Assertion "array_" failed.

memory_pool and exception in thread

I have a test code which allocates instances of A and hands the memory over into a CefRefPtr
a reference counted Wrapper which calls a virtual function Release().
A::Release()obviously needs to destruct and deallocate over the memory pool, therefore I hand in a std::function (A::deleter).
In my test setup (google test) everything works without any problems. However when I use this same loop in a thread (CEF IO Thread) the whole thing crashes with
EXC_BAD_ACCESS (code=EXC_I386_GPFLT) at allocate_node at the third call. I cannot get to the source of the problem. Do you know if a thread can somehow limit the memory allocation. The strange thing is, I can replace the memory_pool with heap_allocator and everything works ?
Note that all my objects get constructed and deleted in the same function the thread is currently...
No resource ownership problems...

Do you have any idea what it could be...?

// A ref counted class (CefRefPtr from Chromium Embedded Framework)
struct A : CefBaseRefCounted
{   
    template<typename D>
    A(int a, D&&d) : m_a{a}, deleter(d) {}
    ~A(){ std::cout << "dtor A :" << m_a[0] << std::endl;}
    int m_a[100];

    std::function<void(A*)> deleter; // Wrap here the deleter to delete over the pool
                                                           
    void AddRef() const override { m_refCount.AddRef(); }
    bool Release() const override 
    {
        if (m_refCount.Release())
        {
            deleter(const_cast<A*>(this));
            return true;
        }
        return false;                                               
    }
    bool HasOneRef() const override { return m_refCount.HasOneRef(); } 
    CefRefCount m_refCount;
};

MY_TEST(MemoryPool, Test1)
{
    using RawAllocator = memory_pool<>;
    using Ptr    = CefRefPtr<A>;
    using RawPtr = std::unique_ptr<A, allocator_deallocator<A, RawAllocator>>;

    RawAllocator pool(sizeof(A), sizeof(A)*10);
    std::vector<Ptr> vec;
    for(auto i = 0; i< 30000; ++i)
    {
        auto memory = pool.allocate_node(); // CRASH HERE at third call
        
         // raw_ptr deallocates memory in case of constructor exception
        RawPtr result(static_cast<A*>(memory), {pool});
        // call constructor (placement new)
        ::new(memory) A(i, [&pool](auto* p){ allocator_deleter<A, RawAllocator>{pool}(p); });
        // pass ownership to return value CefRefPtr which will use the internal A::deleter
        std::cout << "allocated " << i << std::endl;
        vec.emplace_back( Ptr(result.release()) );
    }
    std::shuffle(vec.begin(), vec.end(), std::mt19937{});
}

Cmake version file name is wrong

When compiling with make install using cmake build directory prefix the output file generated to specify version info is named as foonathan_memory-version.cmake whereas cmake tries to look for foonathan_memory-config-version.cmake. This means that if you are trying to use find_package(foonathan_memory 0.6.1) with version number specified it will fail as it cannot find any version info. The file needs to be renamed to avoid this issue.

cross compiling is broken

Firstly, CMAKE_CROSSCOMPILING should be checked, not CMAKE_CROSS_COMPILING. Secondly, even with this fix, compile fails because of an empty container_node_sizes_impl.hpp.

make_block_allocator fails with memory::malloc_allocator

The following fails:

// fails to compile
auto block_alloc = memory::make_block_allocator<memory::malloc_allocator>(1024*1024);
// works
auto block_alloc = memory::growing_block_allocator<memory::malloc_allocator>(1024*1024);

Compiler failure:

/work/third_party/memory/include/foonathan/memory/memory_arena.hpp: In instantiation of ‘foonathan::memory::make_block_allocator_t<BlockOrRawAllocator> foonathan::memory::make_block_allocator(std::size_t, Args&& ...) [with BlockOrRawAllocator = foonathan::memory::detail::lowlevel_allocator<foonathan::memory::detail::malloc_allocator_impl>; Args = {}; foonathan::memory::make_block_allocator_t<BlockOrRawAllocator> = foonathan::memory::growing_block_allocator<foonathan::memory::detail::lowlevel_allocator<foonathan::memory::detail::malloc_allocator_impl>, 2u, 1u>; std::size_t = long unsigned int]’:
/work/trtlab/core/tests/test_memory.cc:813:88:   required from here
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:631:47: error: no matching function for call to ‘make_block_allocator(foonathan::memory::is_block_allocator<foonathan::memory::detail::lowlevel_allocator<foonathan::memory::detail::malloc_allocator_impl> >, std::size_t&)’
                 detail::default_block_wrapper>(is_block_allocator<BlockOrRawAllocator>{},
                                               ^
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:596:28: note: candidate: template<class BlockAllocator, class ... Args> BlockAllocator foonathan::memory::detail::make_block_allocator(std::true_type, std::size_t, Args&& ...)
             BlockAllocator make_block_allocator(std::true_type, std::size_t block_size,
                            ^
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:596:28: note:   template argument deduction/substitution failed:
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:603:18: note: candidate: template<template<class> class Wrapper, class RawAlloc> Wrapper<RawAlloc> foonathan::memory::detail::make_block_allocator(std::false_type, std::size_t, RawAlloc)
             auto make_block_allocator(std::false_type, std::size_t block_size,
                  ^
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:603:18: note:   template argument deduction/substitution failed:
/work/third_party/memory/include/foonathan/memory/memory_arena.hpp:631:47: note:   couldn't deduce template parameter ‘RawAlloc’
                 detail::default_block_wrapper>(is_block_allocator<BlockOrRawAllocator>{},

Prefix of compatibility options

The documentation states that compatibility options can be overridden by setting FOONATHAN_HAS_* options. However, FOONATHAN_HAS_THREAD_LOCAL can only be set by specifying set(COMP_HAS_THREAD_LOCAL OFF CACHE BOOL "" FORCE) in my makefile; thus, the prefix seems to be COMP, and not FOONATHAN.

Incidentally, you might want to disable thread local support on gcc/mingw64; according to the comments in this bug report, thread local support seems rather wonky. Personally, I got SEGFAULT' s on thread exit when using the temporary_allocator; by forcing FOONATHAN_HAS_THREAD_LOCAL to zero when compiling with gcc/MINGW64, everything is fine.

how to store nullptr in unique_ptr

 using RawAllocator = memory_pool<node_pool>;
 using Deleter       = allocator_deleter<uint8_t[], RawAllocator>;
 using RawPtr       = std::unique_ptr<uint8_t[], Deleter>;
 RawAllocator pool(10, 10 * 10);

 RawPtr ptr(nullptr, Deleter{foonathan::memory::make_allocator_reference(pool)});

How can I make a nullptr from a non-default constructible deleter?
The above does somehow not work and gives me the following errors?
What am I doing wrong? ( I need nullptr, to denote, some uninitialized value inside a class)

 error: no matching constructor for initialization of 'RawPtr' (aka 'unique_ptr<uint8_t [], allocator_deleter<uint8_t [], memory_pool<foonathan::memory::node_pool> > >')
    RawPtr ptr(nullptr, {foonathan::memory::make_allocator_reference(pool)});
           ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2708:3: note: candidate constructor [with _Dummy = true, $1 = void] not viable: cannot convert initializer list argument to 'const foonathan::memory::allocator_deleter<unsigned char [], foonathan::memory::memory_pool<foonathan::memory::node_pool>, std::__1::mutex>'
  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2724:3: note: candidate constructor [with _Dummy = true, $1 = void] not viable: cannot convert initializer list argument to 'foonathan::memory::allocator_deleter<unsigned char [], foonathan::memory::memory_pool<foonathan::memory::node_pool>, std::__1::mutex>'
  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2702:3: note: candidate template ignored: requirement '_CheckArrayPointerConversion<nullptr_t>::value' was not satisfied [with _Pp = nullptr_t, _Dummy = true, $2 = void]
  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2715:3: note: candidate template ignored: requirement '_CheckArrayPointerConversion<nullptr_t>::value' was not satisfied [with _Pp = nullptr_t, _Dummy = true, $2 = void]
  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2734:3: note: candidate template ignored: substitution failure [with _Pp = nullptr_t, _Dummy = true]: no type named '__bad_rval_ref_type' in 'std::__1::__dependent_type<std::__1::__unique_ptr_deleter_sfinae<foonathan::memory::allocator_deleter<unsigned char [], foonathan::memory::memory_pool<foonathan::memory::node_pool>, std::__1::mutex> >, true>'
  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2684:13: note: candidate constructor template not viable: requires 0 arguments, but 2 were provided
  constexpr unique_ptr() noexcept : __ptr_(pointer()) {}
            ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2689:13: note: candidate constructor template not viable: requires 1 argument, but 2 were provided
  constexpr unique_ptr(nullptr_t) noexcept : __ptr_(pointer()) {}
            ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2695:12: note: candidate constructor template not viable: requires single argument '__p', but 2 arguments were provided
  explicit unique_ptr(_Pp __p) noexcept
           ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2753:3: note: candidate constructor template not viable: requires single argument '__u', but 2 arguments were provided
  unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2737:3: note: candidate constructor not viable: requires single argument '__u', but 2 arguments were provided
  unique_ptr(unique_ptr&& __u) noexcept
  ^
/usr/local/opt/myllvm6.0rc1/include/c++/v1/memory:2347:28: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
class _LIBCPP_TEMPLATE_VIS unique_ptr {
                           ^

Thread Local Allocator Clear-up

Hi,

Reading through your code I can't see how your Nifty Counter approach clears up the temporary allocators safely . As the temporary_allocator_dtor_t instances are only static and not thread local themselves, their destructors will only be called at program exit and only on one thread. The temporary_allocator_dtor_t thread local data members will only be accessed on that one thread - so their is no point in them being thread local. Any allocators on other threads, including threads that are killed mid program will never be deallocated.

Perhaps my understanding of your solution is wrong.
Nice library, by the way.

missing declaration when FOONATHAN_MEMORY_BUILD_TOOLS=OFF

Setting cmake option FOONATHAN_MEMORY_BUILD_TOOLS=OFF results in an empty header for container_node_sizes_impl.hpp
This results in a build error when including container.hpp, because shared_ptr_stateful_node_size has no definition.

My motivation for setting FOONATHAN_MEMORY_BUILD_TOOLS=OFF is to build for QNX, which does not contain experimental/memory_resource.h

GCC Compilation warnings

GCC print warnings when compile with -Wshadow:

/home/ksergey/dev/gdax_gateway/deps/memory/include/foonathan/memory/error.hpp:35:25: note: shadowed declaration is here
             const void* allocator;
                         ^
/home/ksergey/dev/gdax_gateway/deps/memory/include/foonathan/memory/error.hpp:40:17: warning: declaration of ‘name’ shadows 
a member of ‘foonathan::memory::allocator_info’ [-Wshadow]
                 : name(name),
                 ^

If you fine with that - could you please update CMakeLists.txt (added SYSTEM)?

...
target_include_directories(foonathan_memory SYSTEM PUBLIC $<BUILD_INTERFACE:${FOONATHAN_MEMORY_SOURCE_DIR}/include/> # for client in subdirectory
                                                   $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # for generated files in build mode
                                                   $<INSTALL_INTERFACE:${include_dest}> # for client in install mode

...

Memory pool collection thread safety

First of all thanks for your work, this library is really useful.
I have a question regarding memory pool collection, unlike RawAllocator it is not thread safe. Is this intentional and by design? Does the responsibility to protect the pool lies with developer?

map_node_size

I expected memory::map_node_size to take two template arguments, but rather it only takes one.

Expected:

memory::map_node_size<key_t, value_t>::value

Instead it only takes one template argument T.

What's the correct usage?

// do we use the value_type?
// c++17 gives us node_type
memory::map_node_size<std::map<key_t, value_t>::value_type>::value

multi-threaded guidance

The library offers a couple ways to make the storage of an allocator thread-safe, either by directly or reference storage. However, those storage policies don't get propagated if you extend the allocator into a tracker, as an std_allocator, etc.

If you want to create a stateful allocator whose state should be protected by a mutex in when used as a sub-allocator for higher-level allocators, what is the best practice?

Do you:

  • create your own synchronization mutexes in the allocator
  • create a new raw allocator that hold a thread-safe reference to the stateful (shared?) allocator and provide the link the allocator traits to the reference
  • some other way?

stateful no mutex ubsan alignment error

Ubsan detects some undefined behavior from misalignment in the "stateful no mutex" test in foonathan_memory_test.

I built the code with

cmake \
  -D CMAKE_BUILD_TYPE=Debug \
  -D CMAKE_CXX_FLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -Wall -Wcast-align -Wextra" \
  -D FOONATHAN_MEMORY_BUILD_TESTS=ON ..

The compiler is clang 9.0.1.

./foonathan_memory_test prints out

/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/shared_ptr_base.h:680:6: runtime error: constructor call on misaligned address 0x0000018e0094 for type '_Sp_cp_type' (aka '_Sp_counted_ptr_inplace<int, foonathan::memory::std_allocator<int, foonathan::memory::memory_pool<foonathan::memory::node_pool>, foonathan::memory::no_mutex>, (__gnu_cxx::_Lock_policy)2U>'), which requires 8 byte alignment
0x0000018e0094: note: pointer points here
  fd fd fd fd cd cd cd cd  cd cd cd cd cd cd cd cd  cd cd cd cd cd cd cd cd  cd cd cd cd cd cd cd cd
              ^ 

A backtrace showed the test in test/smart_ptr.cpp.

SECTION("stateful no mutex")
{
  memory_pool<> pool(allocate_shared_node_size<int, memory_pool<>, no_mutex>::value, 1024);
  auto          ptr = allocate_shared<int, no_mutex>(pool, 42);
  REQUIRE(*ptr == 42);
}

nullptr as unique_ptr with Deleter

I have the following problem: I have a class BinaryBuffer which should have a default Ctor:

using Deleter     = foonathan::memory::allocator_deleter<uint8_t[], RawAllocator>;
using BufferPtr  = std::unique_ptr<uint8_t[], Deleter>;

//! Constructor for an empty buffer!
    BinaryBuffer(std::shared_ptr<RawAllocator> allocator)
        : m_allocator(allocator)
        , m_data(nullptr, Deleter{foonathan::memory::make_allocator_reference(*allocator), 0})
    {}

It takes a RawAllocator which it keeps as reference (m_allocator). The data m_data is of type BufferPtr. My problem I am facing is, that I need a valid allocator smart pointer (not nullptr) such that I can setup the Deleter, even if the pointer is actually nullptr. Is there a way of having a default CTOR where I set the m_data member to nullptr, with an invalid deleter.
Is there such a wrapper like make_allocator_pointer(allocator.get()) which wraps a pointer to the allocator internally which I can default to nullptr. Or can this be achieved similarly?

g++5 can not build..........

In file included from /tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:353:0,
                 from /tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:12:
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:69:50: error: expected primary-expression before ‘)’ token
         static auto C(int (*)[FOONATHAN_ALIGNOF(X)]) -> X;
                                                  ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:69:50: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:69:50: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:69:51: error: array bound is not an integer constant before ‘]’ token
         static auto C(int (*)[FOONATHAN_ALIGNOF(X)]) -> X;
                                                   ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:71:28: error: expected ‘;’ at end of member declaration
         static std::size_t FOONATHAN_CONSTEXPR min_val =
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:71:48: error: ‘min_val’ does not name a type
         static std::size_t FOONATHAN_CONSTEXPR min_val =
                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:74:28: error: expected ‘;’ at end of member declaration
         static std::size_t FOONATHAN_CONSTEXPR max_val =
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:74:28: error: redeclaration of ‘std::size_t detail::M1<X, T ...>::FOONATHAN_CONSTEXPR’
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:71:28: note: previous declaration ‘std::size_t detail::M1<X, T ...>::FOONATHAN_CONSTEXPR’
         static std::size_t FOONATHAN_CONSTEXPR min_val =
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:74:48: error: ‘max_val’ does not name a type
         static std::size_t FOONATHAN_CONSTEXPR max_val =
                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:85:28: error: expected ‘;’ at end of member declaration
         static std::size_t FOONATHAN_CONSTEXPR min_val = 1;
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:85:48: error: ‘min_val’ does not name a type
         static std::size_t FOONATHAN_CONSTEXPR min_val = 1;
                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:86:28: error: expected ‘;’ at end of member declaration
         static std::size_t FOONATHAN_CONSTEXPR max_val = 1;
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:86:28: error: redeclaration of ‘std::size_t detail::M1<>::FOONATHAN_CONSTEXPR’
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:85:28: note: previous declaration ‘std::size_t detail::M1<>::FOONATHAN_CONSTEXPR’
         static std::size_t FOONATHAN_CONSTEXPR min_val = 1;
                            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:86:48: error: ‘max_val’ does not name a type
         static std::size_t FOONATHAN_CONSTEXPR max_val = 1;
                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:96:50: error: expected primary-expression before ‘)’ token
         static auto C(int (*)[FOONATHAN_ALIGNOF(X)]) -> M1<>;
                                                  ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:96:50: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:96:51: error: array bound is not an integer constant before ‘]’ token
         static auto C(int (*)[FOONATHAN_ALIGNOF(X)]) -> M1<>;
                                                   ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:83: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
         : M4<M2<S, A>, W<X...>, W<Y..., decltype(S::C((int (*)[FOONATHAN_ALIGNOF(A)])(nullptr)))>>
                                                                                   ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:83: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:41: error: template argument 2 is invalid
         : M4<M2<S, A>, W<X...>, W<Y..., decltype(S::C((int (*)[FOONATHAN_ALIGNOF(A)])(nullptr)))>>
                                         ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:33: error: template argument 3 is invalid
         : M4<M2<S, A>, W<X...>, W<Y..., decltype(S::C((int (*)[FOONATHAN_ALIGNOF(A)])(nullptr)))>>
                                 ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:96: error: expected ‘{’ before ‘)’ token
         : M4<M2<S, A>, W<X...>, W<Y..., decltype(S::C((int (*)[FOONATHAN_ALIGNOF(A)])(nullptr)))>>
                                                                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:109:96: error: expected unqualified-id before ‘)’ token
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:79: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
                                                                               ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:79: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:30: error: template argument 1 is invalid
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
                              ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:27: error: wrong number of template arguments (1, should be 3)
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
                           ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:47:12: note: provided for ‘template<class, class, class> struct detail::M4’
     struct M4; // 'foldl,fmap' dups to M1<>
            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:24: error: template argument 1 is invalid
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
                        ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:21: error: template argument 2 is invalid
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
                     ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:175:12: error: template argument 1 is invalid
         M0<M5<M3<>, M0<M4<M1<decltype(M1<X...>::C((int (*)[FOONATHAN_ALIGNOF(X)])(nullptr)))...>,
            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:186:38: error: ‘M7’ was not declared in this scope
     using unisorted_aligned_ = M0<M6<M7<X...>, M1<X...>::min_val, M1<X...>::max_val>>;
                                      ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:186:42: error: expected parameter pack before ‘...’
     using unisorted_aligned_ = M0<M6<M7<X...>, M1<X...>::min_val, M1<X...>::max_val>>;
                                          ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:186:45: error: wrong number of template arguments (1, should be at least 3)
     using unisorted_aligned_ = M0<M6<M7<X...>, M1<X...>::min_val, M1<X...>::max_val>>;
                                             ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:51:12: note: provided for ‘template<class, long unsigned int <anonymous>, long unsigned int <anonymous>, long unsigned int ...<anonymous> > struct detail::M6’
     struct M6; // Sort by alignof
            ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:186:77: error: wrong number of template arguments (3, should be 1)
     using unisorted_aligned_ = M0<M6<M7<X...>, M1<X...>::min_val, M1<X...>::max_val>>;
                                                                             ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:21:32: note: provided for ‘template<class T> using M0 = typename T::type’
     using M0 = typename T::type;
                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:197:45: error: expected nested-name-specifier before ‘unisorted_aligned_’
     using unisorted_aligned_wrap = typename unisorted_aligned_<X...>::template rebind<W>;
                                             ^
/tmp/Fast-RTPS/thirdparty/memory/tool/test_types.hpp:204:28: error: ‘unisorted_aligned_wrap’ in namespace ‘detail’ does not name a template type
 using test_types = detail::unisorted_aligned_wrap<std::tuple, char, bool, short, int, long,
                            ^
In file included from /tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:12:0:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In function ‘node_size_map debug_impl(Debugger, std::tuple<_Elements ...>)’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:371:51: error: expected primary-expression before ‘)’ token
     int dummy[] = {(result[FOONATHAN_ALIGNOF(Types)] = debug_single<Types>(debugger), 0)...};
                                                   ^
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:371:51: error: there are no arguments to ‘FOONATHAN_ALIGNOF’ that depend on a template parameter, so a declaration of ‘FOONATHAN_ALIGNOF’ must be available [-fpermissive]
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In function ‘debug_result debug(Debugger)’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:51: error: ‘test_types’ was not declared in this scope
     return {debugger.name(), debug_impl(debugger, test_types{})};
                                                   ^
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_forward_list]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_forward_list; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_forward_list::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
     return {debugger.name(), debug_impl(debugger, test_types{})};
                                                                ^
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_list]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_list; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_list::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_set]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_set; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_set::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_multiset]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_multiset; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_multiset::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_unordered_set]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_unordered_set; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_unordered_set::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_unordered_multiset]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_unordered_multiset; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_unordered_multiset::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_map]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_map; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_map::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_multimap]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_multimap; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_multimap::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_unordered_map]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_unordered_map; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_unordered_map::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_unordered_multimap]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_unordered_multimap; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_unordered_multimap::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_shared_ptr_stateless]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_shared_ptr_stateless; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_shared_ptr_stateless::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_shared_ptr_stateful]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_shared_ptr_stateful; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_shared_ptr_stateful::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp: In instantiation of ‘debug_result debug(Debugger) [with Debugger = debug_shared_ptr_stateful_mutex]’:
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:134:21:   required from ‘int serialize_impl(const Serializer&) [with Debugger = debug_shared_ptr_stateful_mutex; Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:141:45:   required from ‘void serialize_impl(const Serializer&, std::tuple<_Elements ...>) [with Serializer = simple_serializer; Debuggers = {debug_forward_list, debug_list, debug_set, debug_multiset, debug_unordered_set, debug_unordered_multiset, debug_map, debug_multimap, debug_unordered_map, debug_unordered_multimap, debug_shared_ptr_stateless, debug_shared_ptr_stateful, debug_shared_ptr_stateful_mutex}]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:149:19:   required from ‘void serialize(const Serializer&) [with Serializer = simple_serializer]’
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.cpp:204:47:   required from here
/tmp/Fast-RTPS/thirdparty/memory/tool/node_size_debugger.hpp:379:64: error: could not convert ‘{debugger.debug_shared_ptr_stateful_mutex::name(), <expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘debug_result’
tool/CMakeFiles/foonathan_memory_node_size_debugger.dir/build.make:62: recipe for target 'tool/CMakeFiles/foonathan_memory_node_size_debugger.dir/node_size_debugger.cpp.o' failed

cmake issue while finding it

I have the following in my installed cmake config foonathan_memroy-config.cmake

get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${SELF_DIR}/${CMAKE_BUILD_TYPE}/foonathan_memory.cmake)

I suppose ${CMAKE_BUILD_TYPE} should have been replaced by "Release" since I installed a release.
Due to that the finding fails.

Do you write these scripts on your own? I would strongly suggest using the cmake built in way (which does the same but adds a bit more elaborate stuff)

from crossguid library , where I just added "modern cmake" support

# Make cmake config files for all targets
install(EXPORT  crossguidTargets
		DESTINATION ${CROSSGUID_CMAKE_CONFIG_INSTALL_DIR}
		FILE crossguid-config.cmake)

where before crossguidTargets is defined as:

install(TARGETS crossguid EXPORT crossguidTargets
		RUNTIME       DESTINATION ${CROSSGUID_RUNTIME_INSTALL_DIR}
		LIBRARY       DESTINATION ${CROSSGUID_LIBRARY_INSTALL_DIR}
		ARCHIVE       DESTINATION ${CROSSGUID_ARCHIVE_INSTALL_DIR}
		FRAMEWORK     DESTINATION ${CROSSGUID_FRAMEWORK_INSTALL_DIR})

I will have look at your install steps, maybe it needs a PR... =)

Unable to generate container_node_sizes_impl.hpp when crosscompiling

The build system currently disables running the nodesize_dbg tool when crosscompiling. The features provided by autogenerating the nodesize_dbg tool seem to mandatory for certain projects so this is breaking my ability to crosscompile the FastRTPS library which recently started using this library.

Pull request #60 proposes a solution to this issue.

cross compiling for QNX segfaults

When cross compile master on QNX, I get a segmentation fault from container_node_sizes_impl.hpp

CMake command with toolchain:
qnx_toolchain.zip

cmake .. -DCMAKE_TOOLCHAIN_FILE=~/Downloads/qnx_toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/brian/qnx700/target/qnx7/x86/usr/local -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=ON -DFOONATHAN_MEMORY_BUILD_EXAMPLES=OFF -DFOONATHAN_MEMORY_BUILD_TESTS=OFF -DFOONATHAN_MEMORY_BUILD_TOOLS=ON

Output:
[ 13%] Generating container_node_sizes_impl.hpp cd /home/brian/Downloads/foonathan_memory/build/src && ../tool/nodesize_dbg --code --alignof "FOONATHAN_ALIGNOF(T)" /home/brian/Downloads/foonathan_memory/build/src/container_node_sizes_impl.hpp Segmentation fault (core dumped) src/CMakeFiles/foonathan_memory.dir/build.make:64: recipe for target 'src/container_node_sizes_impl.hpp' failed make[2]: *** [src/container_node_sizes_impl.hpp] Error 139 make[2]: Leaving directory '/home/brian/Downloads/foonathan_memory/build' CMakeFiles/Makefile2:88: recipe for target 'src/CMakeFiles/foonathan_memory.dir/all' failed make[1]: *** [src/CMakeFiles/foonathan_memory.dir/all] Error 2 make[1]: Leaving directory '/home/brian/Downloads/foonathan_memory/build' Makefile:132: recipe for target 'all' failed make: *** [all] Error 2
build_output.txt

Some url broken?

cmake .. and got this:

-- Checking 13 features
-- Checking for feature alignas
-- Checking for feature alignas - overriden
CMake Error at cmake/comp/comp_base.cmake:288 (message):
  error downloading feature file cpp11_lang/constexpr.cmake: "Couldn't
  connect to server".  Check spelling of feature.

    Trying 151.101.228.133:443...

  TCP_NODELAY set

  connect to 151.101.228.133 port 443 failed: Connection timed out

  Failed to connect to raw.githubusercontent.com port 443: Connection timed
  out

  Closing connection 0

Call Stack (most recent call first):
  cmake/comp/comp_base.cmake:347 (_comp_fetch_feature)
  cmake/comp/comp_base.cmake:369 (_comp_handle_feature)
  cmake/compatibility.cmake:13 (comp_target_features)
  CMakeLists.txt:53 (include)


-- Configuring incomplete, errors occurred!
See also "/tmp/Fast-RTPS/thirdparty/memory/build/CMakeFiles/CMakeOutput.log".

What's the ip suggest.............

memory::allocate_shared

Hi,
I have following code:
memory::memory_pool<> pool(memory::shared_ptr_node_size<int>::value, 256_KiB); auto ptr = memory::allocate_shared<int>(pool, 0);
and this exception is thrown:
if (passed > supported) FOONATHAN_THROW(Ex(info, passed, supported));
passed == 112 and supported == 28

I have no idea what is wrong with my code. Alternative with memory::allocate_unique works. Can you help me?

Thank you

Document basic concepts

In addition to memory-specific concepts already described in docs, it would be useful to describe basic concepts of memory management, such as allocator, arena, pool, etc. This would make the library design easier to understand by newcomers. Also this clarifies the nomenclature used by the library and its docs.

set_node_size not available when cross compiling

This is actually two issues I think (and perhaps simply need answers rather than fixes!).
When cross compiling Fast-RTPS which depends on foonathan_memory (which in my case was also built using cross-compilation immediately prior), I get the following errors:

In file included from /root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.h:32:0,
                 from /root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.cpp:22:
/root/workspace/install/include/foonathan_memory/foonathan/memory/container.hpp:376:31: error: expected template-name before '<' token
         : shared_ptr_node_size<T, std_allocator<T, RawAllocator, Mutex>>
                               ^
/root/workspace/install/include/foonathan_memory/foonathan/memory/container.hpp:376:31: error: expected '{' before '<' token
/root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.cpp:53:46: error: 'set_node_size' is not a member of 'memory'
 constexpr size_t changes_node_size = memory::set_node_size<std::pair<size_t, SequenceNumber_t>>::value;
                                              ^~~~~~~~~~~~~
/root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.cpp:53:46: note: suggested alternative: 'bad_node_size'
 constexpr size_t changes_node_size = memory::set_node_size<std::pair<size_t, SequenceNumber_t>>::value;
                                              ^~~~~~~~~~~~~
                                              bad_node_size
/root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.cpp:53:94: error: expected primary-expression before '>' token
 constexpr size_t changes_node_size = memory::set_node_size<std::pair<size_t, SequenceNumber_t>>::value;
                                                                                              ^~
/root/workspace/src/eProsima/Fast-RTPS/src/cpp/rtps/reader/WriterProxy.cpp:53:98: error: '::value' has not been declared
 constexpr size_t changes_node_size = memory::set_node_size<std::pair<size_t, SequenceNumber_t>>::value;
                                                                                                  ^~~~~

The first (error: expected template-name before '<' token) I resolved/avoided/hacked by adding an additional #if !defined(FOONATHAN_MEMORY_NO_NODE_SIZE) around allocate_shared_node_size in WriterProxy.cpp.

The second('set_node_size' is not a member of 'memory') I'm not sure about. Is this expected to not be available in cross-compile mode? If it is then I'll raise a ticket against Fast-RTPS to avoid using it (since Fast-RTPS is designed for an embedded platform and is expected to be cross-compiled - in my opinion at least 😃).

Cheers!

Minor: CMake dev warnings from comp repo

I've tried building memory which in its turn pulls in comp and got a ton of CMake dev warnings (looks like the submodule is linked to an old commit?):

CMake Warning (dev) at ext/memory/cmake/comp/comp_base.cmake:173 (file):
  Unexpected argument: SHOW_PROGESS
Call Stack (most recent call first):
  ext/memory/cmake/comp/comp_base.cmake:238 (_comp_fetch_feature)
  ext/memory/cmake/comp/comp_base.cmake:255 (_comp_handle_feature)
  ext/memory/cmake/compatibility.cmake:13 (comp_target_features)
  ext/memory/CMakeLists.txt:15 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

Debug fence size causes misalignment.

To enable SSE in the Eigen linear algebra library, data structures need to be 128bit-aligned. However, the FOONATHAN_MEMORY_DEBUG_FENCE default value is 8, which messes up alignment of Eigen structures. I tried to set the size using

set(FOONATHAN_MEMORY_DEBUG_FENCE 16 CACHE STRING "" FORCE)
set(FOONATHAN_MEMORY_DEBUG_FENCE_SIZE 16 CACHE STRING "" FORCE)

to no avail.
How can I configure the size of the debug fence?

A typo in example

There's a missing '#' in example line one. maybe due to Markdown syntax?

Full Documentation online

Would be good to provide the full doxygen documentation online.
There is no class list, and navigating is hard.

e.g.: memory_pool_collection cannot be found...

Thanks a lot!

Building release from tar-ball

When you build from Git, the submodule cmake/comp is checked out. The files are missing from the tar-ball. Is there some easy way to fix this? I quickly tested but it seems the normal "git submodule update" command doesn't work since there is no .git folder in the tar-ball.

This is not a big problem. I can checkout the specific tag for the release and build as normal, but it should be documented if/how we can build from tar-balls.

PS! Is there some specific reason why comp_base.cmake downloads "manually" a selected set of feature files, in stead of the parent project using an extra submodule for the master branch (which will fetch all feature sets). The reason I ask, is that downloading "manually" (when running CMake) failed with a curl error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.