Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
foonathan committed Feb 23, 2016
2 parents dc891ed + 6bb0ba8 commit d8253e5
Show file tree
Hide file tree
Showing 100 changed files with 4,615 additions and 1,858 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ addons:
- g++-4.9
- g++-5
install:
- cmake --version
- wget http://www.cmake.org/files/v3.3/cmake-3.3.1-Linux-x86_64.tar.gz
- wget --no-check-certificate https://www.cmake.org/files/v3.3/cmake-3.3.1-Linux-x86_64.tar.gz
- tar -xzf cmake-3.3.1-Linux-x86_64.tar.gz
- export CC='gcc-4.8'
- export CXX=$compiler
script:
- mkdir $CXX && cd $CXX
- ../cmake-3.3.1-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=$build_type ../
- ../cmake-3.3.1-Linux-x86_64/bin/cmake -DCMAKE_BUILD_TYPE=$build_type -DCMAKE_CXX_FLAGS="-Wall -Wextra -pedantic -Wno-parentheses" ../
- ../cmake-3.3.1-Linux-x86_64/bin/cmake --build .
- ./test/foonathan_memory_test
13 changes: 13 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
0.5
---
* improved CMake build system, now supports cmake installation and `find_package()`
* improved low-level allocators and added `malloc_allocator`
* add virtual memory interface and allocators
* add allocators using a fixed-sized storage block
* introduced `BlockAllocator` concept and various implementations
* new class template `memory_arena` that is used inside the higher level allocators, allows more control over the internal allocations
* add wrappers/adapters for the polymorphic memory resource TS
* improved tracking classes
* other improvements like concept checks and more exception classes
* internal changes

0.4
---
* polished up the interface, many breaking changes in the form of renaming and new header files
Expand Down
84 changes: 15 additions & 69 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015 Jonathan Müller <jonathanmueller.dev@gmail.com>
# Copyright (C) 2015-2016 Jonathan Müller <jonathanmueller.dev@gmail.com>
# This file is subject to the license terms in the LICENSE file
# found in the top-level directory of this distribution.

Expand All @@ -7,75 +7,13 @@
cmake_minimum_required(VERSION 3.1)
project(FOONATHAN_MEMORY)

# compatibility options
include(cmake/compatibility.cmake)

# debug options
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(debug_asserts ON)
set(debug_checks ON)
set(debug_fence 8)
elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo")
set(debug_asserts OFF)
set(debug_checks ON)
set(debug_fence 0)
else()
set(debug_asserts OFF)
set(debug_checks OFF)
set(debug_fence 0)
endif()

option(FOONATHAN_MEMORY_DEBUG_ASSERT
"whether or not internal assertions (like the macro assert) are enabled" ${debug_asserts})
option(FOONATHAN_MEMORY_DEBUG_FILL
"whether or not the (de-)allocated memory will be pre-filled" ${debug_checks})
set(FOONATHAN_MEMORY_DEBUG_FENCE ${debug_fence} CACHE STRING
"the amount of memory used as fence to help catching overflow errors" )
option(FOONATHAN_MEMORY_DEBUG_LEAK_CHECK
"whether or not leak checking is active" ${debug_checks})
option(FOONATHAN_MEMORY_DEBUG_POINTER_CHECK
"whether or not pointer checking on deallocation is active" ${debug_checks})
option(FOONATHAN_MEMORY_DEBUG_DOUBLE_DEALLOC_CHECK
"whether or not the (sometimes expensive) check for double deallocation is active" ${debug_asserts})

# other options
set(FOONATHAN_MEMORY_DEFAULT_ALLOCATOR heap_allocator CACHE STRING
"the default implementation allocator for higher-level ones")
option(FOONATHAN_MEMORY_THREAD_SAFE_REFERENCE
"whether or not allocator_reference is thread safe by default" ON)

# calculates default values for build_* options
if(COMP_HAS_HOSTED_IMPLEMENTATION AND (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR))
# examples/tests if toplevel directory (i.e. direct build, not as subdirectory) and hosted
set(build_examples_tests 1)
else()
set(build_examples_tests 0)
endif()

if(COMP_HAS_HOSTED_IMPLEMENTATION)
set(build_tools 1)
else()
set(build_tools 0)
endif()

option(FOONATHAN_MEMORY_BUILD_EXAMPLES "whether or not to build the examples" ${build_examples_tests})
option(FOONATHAN_MEMORY_BUILD_TESTS "whether or not to build the tests" ${build_examples_tests})
option(FOONATHAN_MEMORY_BUILD_TOOLS "whether or not to build the tools" ${build_tools})

option(FOONATHAN_MEMORY_INCLUDE_PREFIX "whether or not you have to use <foonathan/memory/xxx.hpp>" OFF)
option(FOONATHAN_MEMORY_NAMESPACE_PREFIX "whether or not everything is in namespace foonathan::memory" OFF)

# variables to use library in other projects
if(FOONATHAN_MEMORY_INCLUDE_PREFIX)
set(FOONATHAN_MEMORY_INCLUDE_DIR ${FOONATHAN_MEMORY_SOURCE_DIR}/include/ CACHE PATH
"include directory for library")
else()
set(FOONATHAN_MEMORY_INCLUDE_DIR ${FOONATHAN_MEMORY_SOURCE_DIR}/include/foonathan CACHE PATH
"include directory for library")
endif()

set(FOONATHAN_MEMORY_VERSION_MAJOR 0 CACHE STRING "major version of memory" FORCE)
set(FOONATHAN_MEMORY_VERSION_MINOR 4 CACHE STRING "minor version of memory" FORCE)
set(FOONATHAN_MEMORY_VERSION_MINOR 5 CACHE STRING "minor version of memory" FORCE)
set(FOONATHAN_MEMORY_VERSION "${FOONATHAN_MEMORY_VERSION_MAJOR}.${FOONATHAN_MEMORY_VERSION_MINOR}"
CACHE STRING "version of memory" FORCE)

include(cmake/compatibility.cmake)
include(cmake/configuration.cmake)

# subdirectories
add_subdirectory(src)
Expand All @@ -88,3 +26,11 @@ endif()
if(FOONATHAN_MEMORY_BUILD_TOOLS)
add_subdirectory(tool)
endif()

# exporting
configure_file(cmake/foonathan_memory-config-version.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/foonathan_memory-config-version.cmake
@ONLY)

install(FILES cmake/foonathan_memory-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/foonathan_memory-config-version.cmake DESTINATION ${main_lib_dest})
install(EXPORT foonathan_memory DESTINATION ${lib_dest})
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (C) 2015 Jonathan Müller <jonathanmueller.dev@gmail.com>
Copyright (C) 2015-2016 Jonathan Müller <jonathanmueller.dev@gmail.com>

This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
Expand Down
112 changes: 97 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,112 @@ Over the course of the years many solutions have been proposed. for example [EAS

## Features

* new `RawAllocator` concept that is similar to an `Allocator` but easier to use and write
* implementations of it like memory pools, and other allocator classes
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
* different memory pools
* a portable, improved `alloca()` in the form of `temporary_allocator`
* various adapter classes, e.g. for memory tracking or type-erased references
* std_allocator class that converts a RawAllocator to an Allocator, so they can be used everywhere an Allocator is accepted
* allocator_deleter clases to have deleters that use a RawAllocator

Adapters, wrappers and storage classes:

* incredible powerful `allocator_traits` allowing `Allocator`s as `RawAllocator`s
* `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
* customizable error handling routines that can work with exceptions disabled
* debugging options for leak checking, double-free checks or buffer overflows
* most parts can work on a freestanding implementation
* customizable error handling routines that can work with exceptions disabled
* everything except the STL adapters works on a freestanding environment

## Basic example

```cpp
#include <algorithm>
include <algorithm>
#include <iostream>
#include <iterator>

#include <memory/container.hpp>
#include <memory/memory_pool.hpp>
#include <memory/smart_ptr.hpp>
#include <memory/temporary_allocator.hpp>
#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()
{
// 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, 4096u);

// alias for std::list<int, memory::std_allocator<int, memory::memory_pool<>>
// 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());

// a unique_ptr using the pool
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)
{
Expand All @@ -62,9 +125,14 @@ void merge_sort(BiIter begin, BiIter end)
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::make_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);

Expand All @@ -78,7 +146,7 @@ See `example/` for more.
## Installation
This library is designed to work as [CMake] subdirectory.
This library can be used as [CMake] subdirectory.
It is tested on GCC 4.7-4.9, Clang 3.4-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`.
Expand All @@ -94,6 +162,20 @@ not on the newest version, run `git submodule update
--recursive --remote` to force the compatiblity submodule of memory to
update to the latest version.*
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).
The use an installed library:
4. Call `find_package(foonathan_memory major.minor REQUIRED)` to find the library.
5. Call `target_link_libraries(your_target PUBLIC foonathan_memory)` and activate C++11 to link to the library.
See http://foonathan.github.io/doc/memory/md_doc_installation.html for a detailed guide.
## Documentation
Expand Down
2 changes: 1 addition & 1 deletion cmake/comp
Submodule comp updated 1 files
+109 −25 comp_base.cmake
27 changes: 14 additions & 13 deletions cmake/compatibility.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015 Jonathan Müller <jonathanmueller.dev@gmail.com>
# Copyright (C) 2015-2016 Jonathan Müller <jonathanmueller.dev@gmail.com>
# This file is subject to the license terms in the LICENSE file
# found in the top-level directory of this distribution.

Expand All @@ -7,21 +7,22 @@

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/comp/comp_base.cmake)

# download in source for convenience
set(_foonathan_comp_dest_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/comp)

# dummy library running the required tests
add_library(_foonathan_comp_runner INTERFACE)
comp_target_features(_foonathan_comp_runner INTERFACE
cpp11_lang/alignof cpp11_lang/constexpr cpp11_lang/noexcept cpp11_lang/thread_local
cpp11_lib/max_align_t cpp11_lib/get_new_handler
env/exception_support env/hosted_implementation env/threading_support
PREFIX "FOONATHAN_" NAMESPACE "foonathan_memory_comp"
CMAKE_PATH "${_foonathan_comp_dest_dir}"
add_library(_foonathan_memory_comp_runner INTERFACE)
set(_foonathan_memory_comp_include_path "${CMAKE_CURRENT_BINARY_DIR}")
comp_target_features(_foonathan_memory_comp_runner INTERFACE
cpp11_lang/alignas cpp11_lang/alignof cpp11_lang/constexpr cpp11_lang/noexcept cpp11_lang/thread_local
cpp11_lib/get_new_handler cpp11_lib/max_align_t cpp11_lib/mutex
ts/pmr
env/exception_support env/hosted_implementation
ext/clz
PREFIX "FOONATHAN_" NAMESPACE "foonathan_comp"
INCLUDE_PATH ${_foonathan_memory_comp_include_path}
NOFLAGS)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/foonathan DESTINATION include/comp)

function(_foonathan_use_comp target)
# just activate C++11
comp_target_features(${target} PRIVATE CPP11)
target_link_libraries(${target} PUBLIC _foonathan_comp_runner)
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${_foonathan_memory_comp_include_path}>
$<INSTALL_INTERFACE:include/comp>)
endfunction()
Loading

0 comments on commit d8253e5

Please sign in to comment.