mirror of
https://github.com/matrix-construct/construct
synced 2024-06-09 05:29:00 +02:00
ircd::buffer: Fix template name conflicts for clang-11; apply inline linkages.
ircd::json::tuple: Fix template name related for clang-11. ircd::ctx: Fix template related for clang-11; inline linkages. ircd:Ⓜ️🪝 Fix template related for clang-11.
This commit is contained in:
parent
90c2ecd2e1
commit
30796e5729
|
@ -15,22 +15,28 @@
|
|||
/// the ircd::buffer suite. fixed_buffer should be punnable. Its only memory
|
||||
/// footprint is the array itself and
|
||||
///
|
||||
template<class buffer,
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
struct ircd::buffer::fixed_buffer
|
||||
:std::array<typename std::remove_const<typename buffer::value_type>::type, SIZE>
|
||||
:std::array<typename std::remove_const<typename buffer_type::value_type>::type, SIZE>
|
||||
{
|
||||
using mutable_type = typename std::remove_const<typename buffer::value_type>::type;
|
||||
using mutable_type = typename std::remove_const<typename buffer_type::value_type>::type;
|
||||
using const_type = typename std::add_const<mutable_type>::type;
|
||||
using array_type = std::array<mutable_type, SIZE>;
|
||||
using proto_type = void (const mutable_buffer &);
|
||||
using args_type = const mutable_buffer &;
|
||||
|
||||
operator buffer() const;
|
||||
operator buffer();
|
||||
operator buffer_type() const;
|
||||
operator buffer_type();
|
||||
|
||||
using array_type::array_type;
|
||||
fixed_buffer(const nullptr_t &);
|
||||
fixed_buffer(const std::function<void (const mutable_buffer &)> &closure);
|
||||
fixed_buffer(buffer b);
|
||||
fixed_buffer(buffer_type b);
|
||||
explicit fixed_buffer(nullptr_t);
|
||||
|
||||
template<class F>
|
||||
fixed_buffer(F&&,
|
||||
typename std::enable_if<std::is_invocable<F, args_type>::value, void>::type * = nullptr);
|
||||
|
||||
fixed_buffer() = default;
|
||||
};
|
||||
|
||||
|
@ -41,38 +47,55 @@ static_assert
|
|||
"ircd::buffer::fixed_buffer must be standard layout"
|
||||
);
|
||||
|
||||
template<class buffer,
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
ircd::buffer::fixed_buffer<buffer, SIZE>::fixed_buffer(const nullptr_t &)
|
||||
template<class F>
|
||||
inline
|
||||
ircd::buffer::fixed_buffer<buffer_type, SIZE>::fixed_buffer(F&& closure,
|
||||
typename std::enable_if<std::is_invocable<F, args_type>::value, void>::type *)
|
||||
{
|
||||
closure(mutable_buffer
|
||||
{
|
||||
reinterpret_cast<mutable_buffer::iterator>(this->data()),
|
||||
this->size()
|
||||
});
|
||||
}
|
||||
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
inline
|
||||
ircd::buffer::fixed_buffer<buffer_type, SIZE>::fixed_buffer(nullptr_t)
|
||||
:array_type{{0}}
|
||||
{}
|
||||
|
||||
template<class buffer,
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
ircd::buffer::fixed_buffer<buffer, SIZE>::fixed_buffer(const std::function<void (const mutable_buffer &)> &closure)
|
||||
{
|
||||
closure(mutable_buffer{reinterpret_cast<mutable_buffer::iterator>(this->data()), this->size()});
|
||||
}
|
||||
|
||||
template<class buffer,
|
||||
size_t SIZE>
|
||||
ircd::buffer::fixed_buffer<buffer, SIZE>::fixed_buffer(buffer b)
|
||||
inline
|
||||
ircd::buffer::fixed_buffer<buffer_type, SIZE>::fixed_buffer(buffer_type b)
|
||||
:array_type{std::begin(b), std::end(b)}
|
||||
{}
|
||||
|
||||
template<class buffer,
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
ircd::buffer::fixed_buffer<buffer, SIZE>::operator
|
||||
buffer()
|
||||
inline
|
||||
ircd::buffer::fixed_buffer<buffer_type, SIZE>::operator
|
||||
buffer_type()
|
||||
{
|
||||
return { std::begin(*this), std::end(*this) };
|
||||
return buffer_type
|
||||
{
|
||||
std::begin(*this), std::end(*this)
|
||||
};
|
||||
}
|
||||
|
||||
template<class buffer,
|
||||
template<class buffer_type,
|
||||
size_t SIZE>
|
||||
ircd::buffer::fixed_buffer<buffer, SIZE>::operator
|
||||
buffer()
|
||||
inline
|
||||
ircd::buffer::fixed_buffer<buffer_type, SIZE>::operator
|
||||
buffer_type()
|
||||
const
|
||||
{
|
||||
return { std::begin(*this), std::end(*this) };
|
||||
return buffer_type
|
||||
{
|
||||
std::begin(*this), std::end(*this)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
|
||||
/// Like shared_ptr, this template shares ownership of an allocated buffer
|
||||
///
|
||||
template<class buffer>
|
||||
template<class buffer_type>
|
||||
struct ircd::buffer::shared_buffer
|
||||
:buffer
|
||||
:buffer_type
|
||||
{
|
||||
std::shared_ptr<char> sp;
|
||||
|
||||
shared_buffer(unique_buffer<buffer> &&) noexcept;
|
||||
shared_buffer(unique_buffer<buffer_type> &&) noexcept;
|
||||
explicit shared_buffer(const size_t &size, const size_t &align = 0);
|
||||
explicit shared_buffer(const const_buffer &);
|
||||
shared_buffer() = default;
|
||||
|
@ -27,37 +27,40 @@ struct ircd::buffer::shared_buffer
|
|||
shared_buffer(const shared_buffer &) = default;
|
||||
shared_buffer &operator=(shared_buffer &&) = default;
|
||||
shared_buffer &operator=(const shared_buffer &) = default;
|
||||
shared_buffer &operator=(unique_buffer<buffer> &&) noexcept;
|
||||
shared_buffer &operator=(unique_buffer<buffer_type> &&) noexcept;
|
||||
~shared_buffer() = default;
|
||||
};
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::shared_buffer<buffer>::shared_buffer(const const_buffer &src)
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::shared_buffer<buffer_type>::shared_buffer(const const_buffer &src)
|
||||
:shared_buffer
|
||||
{
|
||||
unique_buffer<buffer>
|
||||
unique_buffer<buffer_type>
|
||||
{
|
||||
src
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::shared_buffer<buffer>::shared_buffer(const size_t &size,
|
||||
const size_t &align)
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::shared_buffer<buffer_type>::shared_buffer(const size_t &size,
|
||||
const size_t &align)
|
||||
:shared_buffer
|
||||
{
|
||||
unique_buffer<buffer>
|
||||
unique_buffer<buffer_type>
|
||||
{
|
||||
size, align
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::shared_buffer<buffer>::shared_buffer(unique_buffer<buffer> &&buf)
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::shared_buffer<buffer_type>::shared_buffer(unique_buffer<buffer_type> &&buf)
|
||||
noexcept
|
||||
:buffer
|
||||
:buffer_type
|
||||
{
|
||||
data(buf), size(buf)
|
||||
}
|
||||
|
@ -69,13 +72,13 @@ noexcept
|
|||
buf.release();
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::shared_buffer<buffer> &
|
||||
ircd::buffer::shared_buffer<buffer>::operator=(unique_buffer<buffer> &&buf)
|
||||
template<class buffer_type>
|
||||
inline ircd::buffer::shared_buffer<buffer_type> &
|
||||
ircd::buffer::shared_buffer<buffer_type>::operator=(unique_buffer<buffer_type> &&buf)
|
||||
noexcept
|
||||
{
|
||||
sp.reset(data(buf), &std::free);
|
||||
*static_cast<buffer *>(this) = buffer
|
||||
*static_cast<buffer_type *>(this) = buffer_type
|
||||
{
|
||||
sp.get(), size(buf)
|
||||
};
|
||||
|
|
|
@ -20,14 +20,14 @@ namespace ircd::allocator
|
|||
|
||||
/// Like unique_ptr, this template holds ownership of an allocated buffer
|
||||
///
|
||||
template<class buffer>
|
||||
template<class buffer_type>
|
||||
struct ircd::buffer::unique_buffer
|
||||
:buffer
|
||||
:buffer_type
|
||||
{
|
||||
bool operator!() const;
|
||||
explicit operator bool() const;
|
||||
bool operator!() const;
|
||||
|
||||
buffer release();
|
||||
buffer_type release();
|
||||
|
||||
unique_buffer() = default;
|
||||
unique_buffer(const size_t &size, const size_t &align = 0);
|
||||
|
@ -39,9 +39,10 @@ struct ircd::buffer::unique_buffer
|
|||
~unique_buffer() noexcept;
|
||||
};
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer>::unique_buffer(const const_buffer &src)
|
||||
:buffer
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::unique_buffer(const const_buffer &src)
|
||||
:buffer_type
|
||||
{
|
||||
allocator::aligned_alloc(0, ircd::buffer::size(src)).release(), ircd::buffer::size(src)
|
||||
}
|
||||
|
@ -58,19 +59,21 @@ ircd::buffer::unique_buffer<buffer>::unique_buffer(const const_buffer &src)
|
|||
copy(dst, src);
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer>::unique_buffer(const size_t &size,
|
||||
const size_t &align)
|
||||
:buffer
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::unique_buffer(const size_t &size,
|
||||
const size_t &align)
|
||||
:buffer_type
|
||||
{
|
||||
allocator::aligned_alloc(align, size).release(), size
|
||||
}
|
||||
{}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer>::unique_buffer(unique_buffer &&other)
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::unique_buffer(unique_buffer &&other)
|
||||
noexcept
|
||||
:buffer
|
||||
:buffer_type
|
||||
{
|
||||
other.release()
|
||||
}
|
||||
|
@ -78,48 +81,49 @@ noexcept
|
|||
assert(std::get<0>(other) == nullptr);
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer> &
|
||||
ircd::buffer::unique_buffer<buffer>::operator=(unique_buffer &&other)
|
||||
template<class buffer_type>
|
||||
inline ircd::buffer::unique_buffer<buffer_type> &
|
||||
ircd::buffer::unique_buffer<buffer_type>::operator=(unique_buffer &&other)
|
||||
& noexcept
|
||||
{
|
||||
this->~unique_buffer();
|
||||
|
||||
static_cast<buffer &>(*this) = other.release();
|
||||
static_cast<buffer_type &>(*this) = other.release();
|
||||
assert(std::get<0>(other) == nullptr);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer>::~unique_buffer()
|
||||
template<class buffer_type>
|
||||
inline
|
||||
ircd::buffer::unique_buffer<buffer_type>::~unique_buffer()
|
||||
noexcept
|
||||
{
|
||||
std::free(const_cast<char *>(this->begin()));
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
buffer
|
||||
ircd::buffer::unique_buffer<buffer>::release()
|
||||
template<class buffer_type>
|
||||
inline buffer_type
|
||||
ircd::buffer::unique_buffer<buffer_type>::release()
|
||||
{
|
||||
const buffer ret{*this};
|
||||
const buffer_type ret{*this};
|
||||
std::get<0>(*this) = nullptr;
|
||||
std::get<1>(*this) = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
ircd::buffer::unique_buffer<buffer>::operator
|
||||
template<class buffer_type>
|
||||
inline bool
|
||||
ircd::buffer::unique_buffer<buffer_type>::operator!()
|
||||
const
|
||||
{
|
||||
return this->buffer_type::empty();
|
||||
}
|
||||
|
||||
template<class buffer_type>
|
||||
inline ircd::buffer::unique_buffer<buffer_type>::operator
|
||||
bool()
|
||||
const
|
||||
{
|
||||
return !this->buffer::empty();
|
||||
}
|
||||
|
||||
template<class buffer>
|
||||
bool
|
||||
ircd::buffer::unique_buffer<buffer>::operator!()
|
||||
const
|
||||
{
|
||||
return this->buffer::empty();
|
||||
return !this->buffer_type::empty();
|
||||
}
|
||||
|
|
|
@ -95,12 +95,12 @@ namespace ircd::ctx
|
|||
#include "dock.h"
|
||||
#include "latch.h"
|
||||
#include "queue.h"
|
||||
#include "mutex.h"
|
||||
#include "shared_mutex.h"
|
||||
#include "upgrade_lock.h"
|
||||
#include "unlock_guard.h"
|
||||
#include "condition_variable.h"
|
||||
#include "scope_notify.h"
|
||||
#include "mutex.h"
|
||||
#include "view.h"
|
||||
#include "shared_state.h"
|
||||
#include "promise.h"
|
||||
|
|
|
@ -194,28 +194,28 @@ ircd::ctx::shared_mutex::unlock()
|
|||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_for(duration&& d)
|
||||
{
|
||||
return try_unlock_upgrade_and_lock_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_for(duration&& d)
|
||||
{
|
||||
return try_unlock_shared_and_lock_upgrade_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_for(duration&& d)
|
||||
{
|
||||
return try_unlock_shared_and_lock_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_until(time_point&& tp)
|
||||
{
|
||||
assert(0);
|
||||
|
@ -223,7 +223,7 @@ ircd::ctx::shared_mutex::try_unlock_upgrade_and_lock_until(time_point&& tp)
|
|||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_until(time_point&& tp)
|
||||
{
|
||||
assert(0);
|
||||
|
@ -231,7 +231,7 @@ ircd::ctx::shared_mutex::try_unlock_shared_and_lock_upgrade_until(time_point&& t
|
|||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_unlock_shared_and_lock_until(time_point&& tp)
|
||||
{
|
||||
assert(0);
|
||||
|
@ -307,28 +307,28 @@ ircd::ctx::shared_mutex::lock()
|
|||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_upgrade_for(duration&& d)
|
||||
{
|
||||
return try_lock_upgrade_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_shared_for(duration&& d)
|
||||
{
|
||||
return try_lock_shared_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_for(duration&& d)
|
||||
{
|
||||
return try_lock_until(system_clock::now() + d);
|
||||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_upgrade_until(time_point&& tp)
|
||||
{
|
||||
assert(current);
|
||||
|
@ -347,7 +347,7 @@ ircd::ctx::shared_mutex::try_lock_upgrade_until(time_point&& tp)
|
|||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_shared_until(time_point&& tp)
|
||||
{
|
||||
assert(current);
|
||||
|
@ -366,7 +366,7 @@ ircd::ctx::shared_mutex::try_lock_shared_until(time_point&& tp)
|
|||
}
|
||||
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::shared_mutex::try_lock_until(time_point&& tp)
|
||||
{
|
||||
assert(current);
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ircd::ctx::upgrade_lock
|
|||
template<class time_point> bool try_lock_until(time_point&&);
|
||||
void unlock();
|
||||
|
||||
mutex *release() noexcept;
|
||||
decltype(auto) release() noexcept;
|
||||
|
||||
template<class r, class p> upgrade_lock(mutex &, const std::chrono::time_point<r, p> &);
|
||||
template<class r, class p> upgrade_lock(mutex &, const std::chrono::duration<r, p> &);
|
||||
|
@ -62,14 +62,16 @@ namespace ircd
|
|||
using ctx::upgrade_lock;
|
||||
}
|
||||
|
||||
template<class mutex>
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m)
|
||||
template<class mutex_type>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex_type>::upgrade_lock(mutex_type &m)
|
||||
:m{&m}
|
||||
{
|
||||
lock();
|
||||
}
|
||||
|
||||
template<class mutex>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
||||
std::defer_lock_t)
|
||||
:m{&m}
|
||||
|
@ -77,6 +79,7 @@ ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
||||
std::adopt_lock_t)
|
||||
:m{&m}
|
||||
|
@ -88,6 +91,7 @@ ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
|||
template<class mutex>
|
||||
template<class rep,
|
||||
class period>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
||||
const std::chrono::duration<rep, period> &rel)
|
||||
:m{&m}
|
||||
|
@ -98,6 +102,7 @@ ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
|||
template<class mutex>
|
||||
template<class rep,
|
||||
class period>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
||||
const std::chrono::time_point<rep, period> &abs)
|
||||
:m{&m}
|
||||
|
@ -106,6 +111,7 @@ ircd::ctx::upgrade_lock<mutex>::upgrade_lock(mutex &m,
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::upgrade_lock(upgrade_lock &&other)
|
||||
noexcept
|
||||
:m{other.release()}
|
||||
|
@ -113,6 +119,7 @@ noexcept
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
inline
|
||||
ircd::ctx::upgrade_lock<mutex>::~upgrade_lock()
|
||||
noexcept
|
||||
{
|
||||
|
@ -121,18 +128,18 @@ noexcept
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
mutex *
|
||||
inline decltype(auto)
|
||||
ircd::ctx::upgrade_lock<mutex>::release()
|
||||
noexcept
|
||||
{
|
||||
mutex *const m{this->m};
|
||||
auto *const m{this->m};
|
||||
this->m = nullptr;
|
||||
return m;
|
||||
}
|
||||
|
||||
template<class mutex>
|
||||
template<class time_point>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::upgrade_lock<mutex>::try_lock_until(time_point&& tp)
|
||||
{
|
||||
assert(m);
|
||||
|
@ -141,7 +148,7 @@ ircd::ctx::upgrade_lock<mutex>::try_lock_until(time_point&& tp)
|
|||
|
||||
template<class mutex>
|
||||
template<class duration>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::upgrade_lock<mutex>::try_lock_for(duration&& d)
|
||||
{
|
||||
assert(m);
|
||||
|
@ -149,7 +156,7 @@ ircd::ctx::upgrade_lock<mutex>::try_lock_for(duration&& d)
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::upgrade_lock<mutex>::try_lock()
|
||||
{
|
||||
assert(m);
|
||||
|
@ -157,7 +164,7 @@ ircd::ctx::upgrade_lock<mutex>::try_lock()
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
void
|
||||
inline void
|
||||
ircd::ctx::upgrade_lock<mutex>::lock()
|
||||
{
|
||||
assert(m);
|
||||
|
@ -165,7 +172,7 @@ ircd::ctx::upgrade_lock<mutex>::lock()
|
|||
}
|
||||
|
||||
template<class mutex>
|
||||
bool
|
||||
inline bool
|
||||
ircd::ctx::upgrade_lock<mutex>::owns_lock()
|
||||
const
|
||||
{
|
||||
|
|
|
@ -11,19 +11,14 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_JSON_TUPLE_KEYS_H
|
||||
|
||||
namespace ircd::json
|
||||
{
|
||||
template<class tuple> struct keys;
|
||||
}
|
||||
|
||||
/// Array of string literals (in string_views) representing just the keys of a
|
||||
/// tuple. By default construction all keys are included in the array. A
|
||||
/// selection construction will only include keys that are selected. Note that
|
||||
/// the selection construction packs all the chosen keys at the front of the
|
||||
/// array so you cannot rely on this for a key's index into the tuple.
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
struct ircd::json::keys
|
||||
:std::array<string_view, tuple::size()>
|
||||
:std::array<string_view, T::size()>
|
||||
{
|
||||
struct selection;
|
||||
struct include;
|
||||
|
@ -40,9 +35,9 @@ struct ircd::json::keys
|
|||
/// Selection of keys in a tuple represented by a bitset. Users generally
|
||||
/// do not construct this class directly. Instead, construct one of the
|
||||
/// `include` or `exclude` classes which will set these bits appropriately.
|
||||
template<class tuple>
|
||||
struct ircd::json::keys<tuple>::selection
|
||||
:std::bitset<tuple::size()>
|
||||
template<class T>
|
||||
struct ircd::json::keys<T>::selection
|
||||
:std::bitset<T::size()>
|
||||
{
|
||||
template<class closure> constexpr bool until(closure&&) const;
|
||||
template<class closure> constexpr void for_each(closure&&) const;
|
||||
|
@ -53,17 +48,17 @@ struct ircd::json::keys<tuple>::selection
|
|||
|
||||
// Note the default all-bits set.
|
||||
constexpr selection(const uint64_t &val = -1)
|
||||
:std::bitset<tuple::size()>{val}
|
||||
:std::bitset<T::size()>{val}
|
||||
{}
|
||||
|
||||
static_assert(tuple::size() <= sizeof(uint64_t) * 8);
|
||||
static_assert(T::size() <= sizeof(uint64_t) * 8);
|
||||
};
|
||||
|
||||
/// Construct this class with a list of keys you want to select for a given
|
||||
/// tuple. This constructs a bitset representing the keys of the tuple and
|
||||
/// lights the bits for your selections.
|
||||
template<class tuple>
|
||||
struct ircd::json::keys<tuple>::include
|
||||
template<class T>
|
||||
struct ircd::json::keys<T>::include
|
||||
:selection
|
||||
{
|
||||
include(const vector_view<const string_view> &list)
|
||||
|
@ -82,8 +77,8 @@ struct ircd::json::keys<tuple>::include
|
|||
/// Construct this class with a list of keys you want to deselect for a given
|
||||
/// tuple. This constructs a bitset representing the keys of the tuple and
|
||||
/// lights the bits which are not in the list.
|
||||
template<class tuple>
|
||||
struct ircd::json::keys<tuple>::exclude
|
||||
template<class T>
|
||||
struct ircd::json::keys<T>::exclude
|
||||
:selection
|
||||
{
|
||||
exclude(const vector_view<const string_view> &list)
|
||||
|
@ -103,35 +98,35 @@ struct ircd::json::keys<tuple>::exclude
|
|||
// selection
|
||||
//
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
void
|
||||
ircd::json::keys<tuple>::selection::set(const string_view &key,
|
||||
const bool &val)
|
||||
ircd::json::keys<T>::selection::set(const string_view &key,
|
||||
const bool &val)
|
||||
{
|
||||
this->set(json::indexof<tuple>(key), val);
|
||||
this->set(json::indexof<T>(key), val);
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
void
|
||||
ircd::json::keys<tuple>::selection::set(const size_t &pos,
|
||||
const bool &val)
|
||||
ircd::json::keys<T>::selection::set(const size_t &pos,
|
||||
const bool &val)
|
||||
{
|
||||
this->std::bitset<tuple::size()>::set(pos, val);
|
||||
this->std::bitset<T::size()>::set(pos, val);
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
bool
|
||||
ircd::json::keys<tuple>::selection::has(const string_view &key)
|
||||
ircd::json::keys<T>::selection::has(const string_view &key)
|
||||
const
|
||||
{
|
||||
return this->test(json::indexof<tuple>(key));
|
||||
return this->test(json::indexof<T>(key));
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
template<class it>
|
||||
constexpr it
|
||||
ircd::json::keys<tuple>::selection::transform(it i,
|
||||
const it end)
|
||||
ircd::json::keys<T>::selection::transform(it i,
|
||||
const it end)
|
||||
const
|
||||
{
|
||||
this->until([&i, &end](auto&& key)
|
||||
|
@ -147,10 +142,10 @@ const
|
|||
return i;
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
template<class closure>
|
||||
constexpr void
|
||||
ircd::json::keys<tuple>::selection::for_each(closure&& function)
|
||||
ircd::json::keys<T>::selection::for_each(closure&& function)
|
||||
const
|
||||
{
|
||||
this->until([&function](auto&& key)
|
||||
|
@ -160,15 +155,15 @@ const
|
|||
});
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
template<class closure>
|
||||
constexpr bool
|
||||
ircd::json::keys<tuple>::selection::until(closure&& function)
|
||||
ircd::json::keys<T>::selection::until(closure&& function)
|
||||
const
|
||||
{
|
||||
for(size_t i(0); i < tuple::size(); ++i)
|
||||
for(size_t i(0); i < T::size(); ++i)
|
||||
if(this->test(i))
|
||||
if(!function(key<tuple>(i)))
|
||||
if(!function(key<T>(i)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -178,23 +173,23 @@ const
|
|||
// keys
|
||||
//
|
||||
|
||||
template<class tuple>
|
||||
ircd::json::keys<tuple>::keys(const selection &selection)
|
||||
template<class T>
|
||||
ircd::json::keys<T>::keys(const selection &selection)
|
||||
{
|
||||
selection.transform(this->begin(), this->end());
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
ircd::json::keys<tuple>::operator
|
||||
template<class T>
|
||||
ircd::json::keys<T>::operator
|
||||
vector_view<const string_view>()
|
||||
const
|
||||
{
|
||||
return { this->data(), this->count() };
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
bool
|
||||
ircd::json::keys<tuple>::has(const string_view &key)
|
||||
ircd::json::keys<T>::has(const string_view &key)
|
||||
const
|
||||
{
|
||||
const auto &start
|
||||
|
@ -211,9 +206,9 @@ const
|
|||
return stop != std::find(start, stop, key);
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
size_t
|
||||
ircd::json::keys<tuple>::count()
|
||||
ircd::json::keys<T>::count()
|
||||
const
|
||||
{
|
||||
size_t i(0);
|
||||
|
|
|
@ -13,16 +13,21 @@
|
|||
|
||||
#include "property.h"
|
||||
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
namespace ircd::json
|
||||
{
|
||||
struct tuple_base;
|
||||
|
||||
//TODO: sort
|
||||
template<class tuple> struct keys;
|
||||
template<class...>
|
||||
struct tuple;
|
||||
|
||||
template<class>
|
||||
struct keys;
|
||||
}
|
||||
|
||||
/// All tuple templates inherit from this non-template type for tagging.
|
||||
struct tuple_base
|
||||
struct ircd::json::tuple_base
|
||||
{
|
||||
// EBO tag
|
||||
// EBO
|
||||
};
|
||||
|
||||
/// A compile-time construct to describe a JSON object's members and types.
|
||||
|
@ -50,7 +55,7 @@ struct tuple_base
|
|||
/// and "null".
|
||||
///
|
||||
template<class... T>
|
||||
struct tuple
|
||||
struct ircd::json::tuple
|
||||
:std::tuple<T...>
|
||||
,tuple_base
|
||||
{
|
||||
|
@ -86,57 +91,60 @@ struct tuple
|
|||
tuple() = default;
|
||||
};
|
||||
|
||||
template<class tuple>
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
|
||||
template<class T>
|
||||
constexpr bool
|
||||
is_tuple()
|
||||
noexcept
|
||||
{
|
||||
return std::is_base_of<tuple_base, tuple>::value;
|
||||
return std::is_base_of<tuple_base, T>::value;
|
||||
}
|
||||
|
||||
template<class tuple,
|
||||
template<class T,
|
||||
class R>
|
||||
using enable_if_tuple = typename std::enable_if<is_tuple<tuple>(), R>::type;
|
||||
using enable_if_tuple = typename std::enable_if<is_tuple<T>(), R>::type;
|
||||
|
||||
template<class tuple,
|
||||
template<class T,
|
||||
class test,
|
||||
class R>
|
||||
using enable_if_tuple_and = typename std::enable_if<is_tuple<tuple>() && test(), R>::type;
|
||||
using enable_if_tuple_and = typename std::enable_if<is_tuple<T>() && test(), R>::type;
|
||||
|
||||
template<class tuple>
|
||||
using tuple_type = typename tuple::tuple_type;
|
||||
template<class T>
|
||||
using tuple_type = typename T::tuple_type;
|
||||
|
||||
template<class tuple>
|
||||
using tuple_size = std::tuple_size<tuple_type<tuple>>;
|
||||
template<class T>
|
||||
using tuple_size = std::tuple_size<tuple_type<T>>;
|
||||
|
||||
template<class tuple,
|
||||
template<class T,
|
||||
size_t i>
|
||||
using tuple_element = typename std::tuple_element<i, tuple_type<tuple>>::type;
|
||||
using tuple_element = typename std::tuple_element<i, tuple_type<T>>::type;
|
||||
|
||||
template<class tuple,
|
||||
template<class T,
|
||||
size_t i>
|
||||
using tuple_value_type = typename tuple_element<tuple, i>::value_type;
|
||||
using tuple_value_type = typename tuple_element<T, i>::value_type;
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
inline auto &
|
||||
stdcast(const tuple &o)
|
||||
stdcast(const T &o)
|
||||
{
|
||||
return static_cast<const typename tuple::tuple_type &>(o);
|
||||
return static_cast<const typename T::tuple_type &>(o);
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
template<class T>
|
||||
inline auto &
|
||||
stdcast(tuple &o)
|
||||
stdcast(T &o)
|
||||
{
|
||||
return static_cast<typename tuple::tuple_type &>(o);
|
||||
return static_cast<typename T::tuple_type &>(o);
|
||||
}
|
||||
|
||||
template<class tuple>
|
||||
constexpr enable_if_tuple<tuple, size_t>
|
||||
template<class T>
|
||||
constexpr enable_if_tuple<T, size_t>
|
||||
size()
|
||||
noexcept
|
||||
{
|
||||
return tuple_size<tuple>::value;
|
||||
return tuple_size<T>::value;
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
@ -376,7 +384,7 @@ const
|
|||
|
||||
return crh::sha256::buf
|
||||
{
|
||||
[&preimage](auto &buf)
|
||||
[&preimage](auto&& buf)
|
||||
{
|
||||
sha256{buf, const_buffer{preimage}};
|
||||
}
|
||||
|
|
|
@ -140,11 +140,11 @@ final
|
|||
};
|
||||
|
||||
/// Hook function with a template class as the payload
|
||||
template<class data>
|
||||
template<class data_type>
|
||||
struct ircd::m::hook::hook
|
||||
:base
|
||||
{
|
||||
std::function<void (const m::event &, data)> function;
|
||||
std::function<void (const m::event &, data_type)> function;
|
||||
|
||||
public:
|
||||
hook(const json::members &feature, decltype(function) function)
|
||||
|
@ -159,15 +159,15 @@ struct ircd::m::hook::hook
|
|||
};
|
||||
|
||||
/// Hook site for functions with a template class as the payload
|
||||
template<class data>
|
||||
template<class data_type>
|
||||
struct ircd::m::hook::site
|
||||
:base::site
|
||||
{
|
||||
void call(hook<data> &hfn, const event &event, data d);
|
||||
void call(hook<data_type> &hfn, const event &event, data_type d);
|
||||
|
||||
public:
|
||||
void operator()(base **const &, const event &event, data d);
|
||||
void operator()(const event &event, data d);
|
||||
void operator()(base **const &, const event &event, data_type d);
|
||||
void operator()(const event &event, data_type d);
|
||||
|
||||
site(const json::members &feature)
|
||||
:base::site{feature}
|
||||
|
|
|
@ -135,7 +135,7 @@ struct ircd::run::changed
|
|||
/// satisfied (or if already satisfied) the run::level is checked to be RUN
|
||||
/// otherwise an exception is thrown.
|
||||
///
|
||||
template<class exception>
|
||||
template<class E>
|
||||
struct ircd::run::barrier
|
||||
{
|
||||
template<class... args>
|
||||
|
@ -143,7 +143,7 @@ struct ircd::run::barrier
|
|||
{
|
||||
changed::wait({level::RUN, level::QUIT});
|
||||
if(unlikely(level != level::RUN))
|
||||
throw exception
|
||||
throw E
|
||||
{
|
||||
std::forward<args>(a)...
|
||||
};
|
||||
|
|
|
@ -602,7 +602,7 @@ ircd::m::verify(const event &event,
|
|||
|
||||
const ed25519::sig sig
|
||||
{
|
||||
[&origin_sigs, &keyid](auto &buf)
|
||||
[&origin_sigs, &keyid](auto&& buf)
|
||||
{
|
||||
b64::decode(buf, json::string(origin_sigs.at(keyid)));
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ ircd::m::verify(const m::keys &keys)
|
|||
|
||||
const ed25519::pk pk
|
||||
{
|
||||
[&key](auto &pk)
|
||||
[&key](auto&& pk)
|
||||
{
|
||||
b64::decode(pk, unquote(key.at("key")));
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ ircd::m::verify(const m::keys &keys)
|
|||
|
||||
const ed25519::sig sig
|
||||
{
|
||||
[&server_signatures, &key_id](auto &sig)
|
||||
[&server_signatures, &key_id](auto&& sig)
|
||||
{
|
||||
b64::decode(sig, unquote(server_signatures.at(key_id)));
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ const
|
|||
{
|
||||
const ed25519::pk pk
|
||||
{
|
||||
[&keyb64](auto &buf)
|
||||
[&keyb64](auto&& buf)
|
||||
{
|
||||
b64::decode(buf, keyb64);
|
||||
}
|
||||
|
|
|
@ -231,7 +231,7 @@ const
|
|||
{
|
||||
const ed25519::sig sig
|
||||
{
|
||||
[&sig_](auto &buf)
|
||||
[&sig_](auto&& buf)
|
||||
{
|
||||
b64::decode(buf, sig_);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue