Commit 0af760b7 authored by Florian Oetke's avatar Florian Oetke
Browse files

physfs update and new asset system

parent 151ed0c1
......@@ -27,7 +27,7 @@ BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakStringLiterals: true
ColumnLimit: 100
ColumnLimit: 110
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2
......@@ -61,7 +61,7 @@ PenaltyBreakComment: 400
PenaltyBreakFirstLessLess: 200
PenaltyBreakString: 150
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 10000
PenaltyReturnTypeOnItsOwnLine: 1000000
PointerAlignment: Left
ReflowComments: false
SortIncludes: true
......
......@@ -10,6 +10,7 @@ if(MIRRAGE_BUILD_MESH_CONVERTER)
add_subdirectory(stb_image)
endif()
add_subdirectory(asyncplusplus)
add_subdirectory(enet)
add_subdirectory(glm)
include(gsl_interface.cmake)
......@@ -18,11 +19,13 @@ include(nuklear_interface.cmake)
add_subdirectory(magic_get)
SET(PHYSFS_INTERNAL_ZLIB TRUE)
#SET(PHYSFS_INTERNAL_ZLIB TRUE)
SET(PHYSFS_ARCHIVE_7Z FALSE)
SET(PHYSFS_BUILD_SHARED FALSE)
add_subdirectory(physfs)
include(robin-map_interface.cmake)
add_subdirectory(sdl_vulkan)
add_subdirectory(sf2)
# Compiled Object files
*.slo
*.lo
*.o
# Compiled Dynamic libraries
*.so
*.dylib
# Compiled Static libraries
*.lai
*.la
*.a
# Copyright (c) 2015 Amanieu d'Antras
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
cmake_minimum_required(VERSION 3.1)
project(Async++ C CXX)
option(BUILD_SHARED_LIBS "Build Async++ as a shared library" OFF)
option(USE_CXX_EXCEPTIONS "Enable C++ exception support" ON)
if (APPLE)
option(BUILD_FRAMEWORK "Build a Mac OS X framework instead of a library" OFF)
if (BUILD_FRAMEWORK AND NOT BUILD_SHARED_LIBS)
message(FATAL_ERROR "Can't build a framework with static libraries")
endif()
endif()
# Add all source and header files so IDEs can see them
set(ASYNCXX_INCLUDE
${PROJECT_SOURCE_DIR}/include/async++/aligned_alloc.h
${PROJECT_SOURCE_DIR}/include/async++/cancel.h
${PROJECT_SOURCE_DIR}/include/async++/continuation_vector.h
${PROJECT_SOURCE_DIR}/include/async++/parallel_for.h
${PROJECT_SOURCE_DIR}/include/async++/parallel_invoke.h
${PROJECT_SOURCE_DIR}/include/async++/parallel_reduce.h
${PROJECT_SOURCE_DIR}/include/async++/partitioner.h
${PROJECT_SOURCE_DIR}/include/async++/range.h
${PROJECT_SOURCE_DIR}/include/async++/ref_count.h
${PROJECT_SOURCE_DIR}/include/async++/scheduler.h
${PROJECT_SOURCE_DIR}/include/async++/scheduler_fwd.h
${PROJECT_SOURCE_DIR}/include/async++/task.h
${PROJECT_SOURCE_DIR}/include/async++/task_base.h
${PROJECT_SOURCE_DIR}/include/async++/traits.h
${PROJECT_SOURCE_DIR}/include/async++/when_all_any.h
)
set(ASYNCXX_SRC
${PROJECT_SOURCE_DIR}/src/internal.h
${PROJECT_SOURCE_DIR}/src/fifo_queue.h
${PROJECT_SOURCE_DIR}/src/scheduler.cpp
${PROJECT_SOURCE_DIR}/src/singleton.h
${PROJECT_SOURCE_DIR}/src/task_wait_event.h
${PROJECT_SOURCE_DIR}/src/threadpool_scheduler.cpp
${PROJECT_SOURCE_DIR}/src/work_steal_queue.h
)
source_group(include FILES ${PROJECT_SOURCE_DIR}/include/async++.h ${ASYNCXX_INCLUDE})
source_group(src FILES ${ASYNCXX_SRC})
add_library(Async++ ${PROJECT_SOURCE_DIR}/include/async++.h ${ASYNCXX_INCLUDE} ${ASYNCXX_SRC})
# Async++ only depends on the C++11 standard libraries, but some implementations
# require the -pthread compiler flag to enable threading functionality.
if (NOT MSVC)
target_compile_options(Async++ PRIVATE -std=c++11)
endif()
if (APPLE)
# Use libc++ on Mac because the shipped libstdc++ version is ancient
target_compile_options(Async++ PRIVATE -stdlib=libc++)
set_target_properties(Async++ PROPERTIES LINK_FLAGS -stdlib=libc++)
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(Async++ PUBLIC Threads::Threads)
# Minimize the set of symbols exported by libraries
#set_target_properties(Async++ PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON)
# Set up preprocessor definitions
target_include_directories(Async++ PRIVATE ${PROJECT_SOURCE_DIR}/include)
set_target_properties(Async++ PROPERTIES DEFINE_SYMBOL LIBASYNC_BUILD)
if (NOT BUILD_SHARED_LIBS)
target_compile_definitions(Async++ PUBLIC LIBASYNC_STATIC)
endif()
# Enable warnings for strict C++ standard conformance
if (NOT MSVC)
target_compile_options(Async++ PRIVATE -Wall -Wextra -pedantic)
endif()
# Async++ doesn't make use of RTTI information, so don't generate it
if (MSVC)
target_compile_options(Async++ PRIVATE /GR-)
else()
target_compile_options(Async++ PRIVATE -fno-rtti)
endif()
# Allow disabling exceptions, but warn the user about the consequences
if (NOT USE_CXX_EXCEPTIONS)
message(WARNING "Exceptions have been disabled. Any operation that would "
"throw an exception will result in a call to std::abort() instead.")
target_compile_definitions(Async++ PUBLIC LIBASYNC_NO_EXCEPTIONS)
if (MSVC)
target_compile_options(Async++ PUBLIC /EHs-c-)
else()
target_compile_options(Async++ PUBLIC -fno-exceptions)
endif()
endif()
# Install the library and produce a CMake export script
install(TARGETS Async++
EXPORT Async++
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
FRAMEWORK DESTINATION Frameworks
)
export(EXPORT Async++)
install(EXPORT Async++ DESTINATION cmake)
if (APPLE AND BUILD_FRAMEWORK)
set_target_properties(Async++ PROPERTIES OUTPUT_NAME Async++ FRAMEWORK ON)
set_source_files_properties(${ASYNCXX_INCLUDE} PROPERTIES MACOSX_PACKAGE_LOCATION Headers/async++)
set_source_files_properties(${PROJECT_SOURCE_DIR}/include/async++.h PROPERTIES MACOSX_PACKAGE_LOCATION Headers)
else()
set_target_properties(Async++ PROPERTIES OUTPUT_NAME async++)
target_include_directories(Async++ INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
install(FILES ${PROJECT_SOURCE_DIR}/include/async++.h DESTINATION include)
install(FILES ${ASYNCXX_INCLUDE} DESTINATION include/async++)
endif()
SET(CPACK_GENERATOR "DEB")
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "none") #required
INCLUDE(CPack)
Copyright (c) 2015 Amanieu d'Antras
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Async++
=======
Async++ is a lightweight concurrency framework for C++11. The concept was inspired by the [Microsoft PPL library](http://msdn.microsoft.com/en-us/library/dd492418.aspx) and the [N3428](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf) C++ standard proposal.
Example
-------
Here is a short example which shows some features of Async++:
```c++
#include <iostream>
#include <async++.h>
int main()
{
auto task1 = async::spawn([] {
std::cout << "Task 1 executes asynchronously" << std::endl;
});
auto task2 = async::spawn([]() -> int {
std::cout << "Task 2 executes in parallel with task 1" << std::endl;
return 42;
});
auto task3 = task2.then([](int value) -> int {
std::cout << "Task 3 executes after task 2, which returned "
<< value << std::endl;
return value * 3;
});
auto task4 = async::when_all(task1, task3);
auto task5 = task4.then([](std::tuple<async::task<void>,
async::task<int>> results) {
std::cout << "Task 5 executes after tasks 1 and 3. Task 3 returned "
<< std::get<1>(results).get() << std::endl;
});
task5.get();
std::cout << "Task 5 has completed" << std::endl;
async::parallel_invoke([] {
std::cout << "This is executed in parallel..." << std::endl;
}, [] {
std::cout << "with this" << std::endl;
});
async::parallel_for(async::irange(0, 5), [](int x) {
std::cout << x;
});
std::cout << std::endl;
int r = async::parallel_reduce({1, 2, 3, 4}, 0, [](int x, int y) {
return x + y;
});
std::cout << "The sum of {1, 2, 3, 4} is " << r << std::endl;
}
// Output (order may vary in some places):
// Task 1 executes asynchronously
// Task 2 executes in parallel with task 1
// Task 3 executes after task 2, which returned 42
// Task 5 executes after tasks 1 and 3. Task 3 returned 126
// Task 5 has completed
// This is executed in parallel...
// with this
// 01234
// The sum of {1, 2, 3, 4} is 10
```
Supported Platforms
-------------------
The only requirement to use Async++ is a C++11 compiler and standard library. Unfortunately C++11 is not yet fully implemented on most platforms. Here is the list of OS and compiler combinations which are known to work.
- Linux: Works with GCC 4.7+, Clang 3.2+ and Intel compiler 15+.
- Mac: Works with Apple Clang (using libc++). GCC also works but you must get a recent version (4.7+).
- iOS: Works with Apple Clang (using libc++). Note: because iOS has no thread local support, the library uses a workaround based on pthreads.
- Windows: Works with GCC 4.8+ (with pthread-win32) and Visual Studio 2013+.
Building and Installing
-----------------------
Instructions for compiling Async++ and using it in your code are available on the [Building and Installing](https://github.com/Amanieu/asyncplusplus/wiki/Building-and-Installing) page.
Documentation
------------
The Async++ documentation is split into four parts:
- [Tasks](https://github.com/Amanieu/asyncplusplus/wiki/Tasks): This describes task objects which are the core Async++. Reading this first is strongly recommended.
- [Parallel algorithms](https://github.com/Amanieu/asyncplusplus/wiki/Parallel-algorithms): This describes functions to run work on ranges in parallel.
- [Schedulers](https://github.com/Amanieu/asyncplusplus/wiki/Schedulers): This describes the low-level details of Async++ and how to customize it.
- [API Reference](https://github.com/Amanieu/asyncplusplus/wiki/API-Reference): This gives detailed descriptions of all the classes and functions available in Async++.
Contact
-------
You can contact me by email at amanieu@gmail.com.
// Copyright (c) 2015 Amanieu d'Antras
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <async++.h>
#include <gtk/gtk.h>
#include <iostream>
#include <chrono>
#include <string>
// Scheduler implementation
class gtk_scheduler_impl {
// Get the task from the void* and execute it in the UI thread
static gboolean callback(void* p)
{
async::task_run_handle::from_void_ptr(p).run();
return FALSE;
}
public:
// Convert a task to void* and send it to the gtk main loop
void schedule(async::task_run_handle t)
{
g_idle_add(callback, t.to_void_ptr());
}
};
// Scheduler to run a task in the gtk main loop
gtk_scheduler_impl& gtk_scheduler()
{
static gtk_scheduler_impl sched;
return sched;
}
// In order to ensure the UI is always responsive, you can disallow blocking
// calls in the UI thread. Note that the wait handler isn't called when the
// result of a task is already available, so you can still call .get() on a
// completed task. This is completely optional and can be omitted if you don't
// need it.
void gtk_wait_handler(async::task_wait_handle)
{
std::cerr << "Error: Blocking wait in UI thread" << std::endl;
std::abort();
}
// Thread which increments the label value every ms
void label_update_thread(GtkLabel *label)
{
int counter = 0;
while (true) {
// Sleep for 1ms
std::this_thread::sleep_for(std::chrono::milliseconds(1));
counter++;
// Update the label contents in the UI thread
async::spawn(gtk_scheduler(), [label, counter] {
gtk_label_set_text(label, std::to_string(counter).c_str());
});
}
}
int main(int argc, char *argv[])
{
// Initialize GTK
gtk_init(&argc, &argv);
// Set wait handler on GTK thread to disallow waiting for tasks
async::set_thread_wait_handler(gtk_wait_handler);
// Create a window with a label
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
GtkLabel *label = GTK_LABEL(gtk_label_new("-"));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(label));
gtk_widget_show_all(window);
// Start a secondary thread to update the label
std::thread(label_update_thread, label).detach();
// Go to GTK main loop
gtk_main();
}
// Copyright (c) 2015 Amanieu d'Antras
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef ASYNCXX_H_
#define ASYNCXX_H_
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <iterator>
#include <memory>
#include <mutex>
#include <thread>
#include <type_traits>
#include <utility>
#include <vector>
// Export declaration to make symbols visible for dll/so
#ifdef LIBASYNC_STATIC
# define LIBASYNC_EXPORT
# define LIBASYNC_EXPORT_EXCEPTION
#else
# ifdef _WIN32
# ifdef LIBASYNC_BUILD
# define LIBASYNC_EXPORT __declspec(dllexport)
# else
# define LIBASYNC_EXPORT __declspec(dllimport)
# endif
# define LIBASYNC_EXPORT_EXCEPTION
# else
# define LIBASYNC_EXPORT __attribute__((visibility("default")))
# define LIBASYNC_EXPORT_EXCEPTION __attribute__((visibility("default")))
# endif
#endif
// Support compiling without exceptions
#ifndef LIBASYNC_NO_EXCEPTIONS
# ifdef __clang__
# if !defined(__EXCEPTIONS) || !__has_feature(cxx_exceptions)
# define LIBASYNC_NO_EXCEPTIONS
# endif
# elif defined(__GNUC__) && !defined(__EXCEPTIONS)
# define LIBASYNC_NO_EXCEPTIONS
# elif defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
# define LIBASYNC_NO_EXCEPTIONS
# endif
#endif
#ifdef LIBASYNC_NO_EXCEPTIONS
# define LIBASYNC_THROW(...) std::abort()
# define LIBASYNC_RETHROW() do {} while (false)
# define LIBASYNC_RETHROW_EXCEPTION(except) std::terminate()
# define LIBASYNC_TRY if (true)
# define LIBASYNC_CATCH(...) else if (false)
#else
# define LIBASYNC_THROW(...) throw __VA_ARGS__
# define LIBASYNC_RETHROW() throw
# define LIBASYNC_RETHROW_EXCEPTION(except) std::rethrow_exception(except)
# define LIBASYNC_TRY try
# define LIBASYNC_CATCH(...) catch (__VA_ARGS__)
#endif
// Optional debug assertions. If exceptions are enabled then use those, but
// otherwise fall back to an assert message.
#ifndef NDEBUG
# ifndef LIBASYNC_NO_EXCEPTIONS
# define LIBASYNC_ASSERT(pred, except, message) ((pred) ? ((void)0) : throw except(message))
# else
# define LIBASYNC_ASSERT(pred, except, message) ((pred) ? ((void)0) : assert(message))
# endif
#else
# define LIBASYNC_ASSERT(pred, except, message) ((void)0)
#endif
// Annotate move constructors and move assignment with noexcept to allow objects
// to be moved if they are in containers. Compilers which don't support noexcept
// will usually move regardless.
#if defined(__GNUC__) || _MSC_VER >= 1900
# define LIBASYNC_NOEXCEPT noexcept
#else
# define LIBASYNC_NOEXCEPT throw()
#endif
// Cacheline alignment to avoid false sharing between different threads
#define LIBASYNC_CACHELINE_SIZE 64
#ifdef __GNUC__
# define LIBASYNC_CACHELINE_ALIGN __attribute__((aligned(LIBASYNC_CACHELINE_SIZE)))
#elif defined(_MSC_VER)
# define LIBASYNC_CACHELINE_ALIGN __declspec(align(LIBASYNC_CACHELINE_SIZE))
#else
# define LIBASYNC_CACHELINE_ALIGN alignas(LIBASYNC_CACHELINE_SIZE)
#endif
#ifndef LIBASYNC_STATIC
// Force symbol visibility to hidden unless explicity exported
#if defined(__GNUC__) && !defined(_WIN32)
# pragma GCC visibility push(hidden)
#endif
#endif
// Some forward declarations
namespace async {
template<typename Result>
class task;
template<typename Result>
class shared_task;
template<typename Result>
class event_task;
} // namespace async
// Include sub-headers
#include "async++/traits.h"
#include "async++/aligned_alloc.h"
#include "async++/ref_count.h"
#include "async++/scheduler_fwd.h"
#include "async++/continuation_vector.h"
#include "async++/task_base.h"
#include "async++/scheduler.h"
#include "async++/task.h"
#include "async++/when_all_any.h"
#include "async++/cancel.h"
#include "async++/range.h"
#include "async++/partitioner.h"
#include "async++/parallel_invoke.h"
#include "async++/parallel_for.h"
#include "async++/parallel_reduce.h"
#ifndef LIBASYNC_STATIC
#if defined(__GNUC__) && !defined(_WIN32)
# pragma GCC visibility pop
#endif
#endif
#endif
// Copyright (c) 2015 Amanieu d'Antras
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
namespace async {
namespace detail {
// Allocate an aligned block of memory
LIBASYNC_EXPORT void* aligned_alloc(std::size_t size, std::size_t align);
// Free an aligned block of memory
LIBASYNC_EXPORT void aligned_free(void* addr) LIBASYNC_NOEXCEPT;
// Class representing an aligned array and its length
template<typename T, std::size_t Align = std::alignment_of<T>::value>
class aligned_array {
std::size_t length;
T* ptr;
public:
aligned_array()
: length(0), ptr(nullptr) {}
aligned_array(std::nullptr_t)
: length(0), ptr(nullptr) {}
explicit aligned_array(std::size_t length)
: length(length)
{
ptr = static_cast<T*>(aligned_alloc(length * sizeof(T), Align));
std::size_t i;
LIBASYNC_TRY {
for (i = 0; i < length; i++)
new(ptr + i) T;
} LIBASYNC_CATCH(...) {
for (std::size_t j = 0; j < i; j++)
ptr[i].~T();