chromium/third_party/vulkan-validation-layers/src/layers/external/inplace_function.h

// https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h
// Doc: https://github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf

/*
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#pragma once

#include <type_traits>
#include <utility>
#include <functional>

#ifndef SG14_INPLACE_FUNCTION_THROW
#define SG14_INPLACE_FUNCTION_THROW(x)
#endif

namespace stdext {

namespace inplace_function_detail {

static constexpr size_t InplaceFunctionDefaultCapacity =;

#ifndef SG14_USE_STD_ALIGNED_STORAGE
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61458
// MSVC 32-bit has the same bug.
// libc++ and MSVC 64-bit seem to work fine right now, but why run the risk?
template <size_t Cap>
union aligned_storage_helper {};

template <size_t Cap, size_t Align = alignof(aligned_storage_helper<Cap>)>
struct aligned_storage {};

aligned_storage_t;
static_assert;
static_assert;
#else
using std::aligned_storage;
using std::aligned_storage_t;
static_assert(sizeof(std::aligned_storage_t<sizeof(void*)>) == sizeof(void*), "C");
static_assert(alignof(std::aligned_storage_t<sizeof(void*)>) == alignof(void*), "D");
#endif

template <class T>
struct wrapper {};

template <class R, class... Args>
struct vtable {};

empty_vtable;

template <size_t DstCap, size_t DstAlign, size_t SrcCap, size_t SrcAlign>
struct is_valid_inplace_dst : std::true_type {};

// C++11 MSVC compatible implementation of std::is_invocable_r.

template <class R>
void accept(R);

template <class, class R, class F, class... Args>
struct is_invocable_r_impl : std::false_type {};

is_invocable_r_impl<decltype(std::declval<F>()(std::declval<Args>()...) , void()), void, F, Args...>;

is_invocable_r_impl<decltype(std::declval<F>()(std::declval<Args>()...) , void()), const void, F, Args...>;

is_invocable_r_impl<decltype(accept<R>(std::declval<F>()(std::declval<Args>()...))), R, F, Args...>;

is_invocable_r;
}  // namespace inplace_function_detail

template <class Signature, size_t Capacity = inplace_function_detail::InplaceFunctionDefaultCapacity,
          size_t Alignment = alignof(inplace_function_detail::aligned_storage_t<Capacity>)>
class inplace_function;  // unspecified

namespace inplace_function_detail {
template <class>
struct is_inplace_function : std::false_type {};
is_inplace_function<inplace_function<Sig, Cap, Align>>;
}  // namespace inplace_function_detail

inplace_function<R (Args...), Capacity, Alignment>;

}  // namespace stdext