mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Implement fill_array() utility
This commit is contained in:
parent
ccb89bd76a
commit
7dae376646
@ -63,9 +63,9 @@ void set_nonblocking(int s)
|
|||||||
|
|
||||||
struct gdb_cmd
|
struct gdb_cmd
|
||||||
{
|
{
|
||||||
std::string cmd;
|
std::string cmd{};
|
||||||
std::string data;
|
std::string data{};
|
||||||
u8 checksum;
|
u8 checksum{};
|
||||||
};
|
};
|
||||||
|
|
||||||
bool check_errno_again()
|
bool check_errno_again()
|
||||||
|
@ -16,7 +16,7 @@ class gdb_thread
|
|||||||
|
|
||||||
int server_socket = -1;
|
int server_socket = -1;
|
||||||
int client_socket = -1;
|
int client_socket = -1;
|
||||||
std::weak_ptr<cpu_thread> selected_thread;
|
std::weak_ptr<cpu_thread> selected_thread{};
|
||||||
u64 continue_ops_thread_id = ANY_THREAD;
|
u64 continue_ops_thread_id = ANY_THREAD;
|
||||||
u64 general_ops_thread_id = ANY_THREAD;
|
u64 general_ops_thread_id = ANY_THREAD;
|
||||||
|
|
||||||
|
@ -141,8 +141,8 @@ namespace id_manager
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct id_map
|
struct id_map
|
||||||
{
|
{
|
||||||
std::vector<std::pair<id_key, std::shared_ptr<void>>> vec;
|
std::vector<std::pair<id_key, std::shared_ptr<void>>> vec{};
|
||||||
shared_mutex mutex; // TODO: Use this instead of global mutex
|
shared_mutex mutex{}; // TODO: Use this instead of global mutex
|
||||||
|
|
||||||
id_map()
|
id_map()
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,8 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
struct memory_block_data
|
struct memory_block_data
|
||||||
{
|
{
|
||||||
std::vector<u8> data;
|
std::vector<u8> data{};
|
||||||
|
|
||||||
template<typename Archive>
|
template<typename Archive>
|
||||||
void serialize(Archive& ar)
|
void serialize(Archive& ar)
|
||||||
{
|
{
|
||||||
@ -96,8 +97,8 @@ namespace rsx
|
|||||||
// bleh, may need to break these out, might be unnecessary to do both always
|
// bleh, may need to break these out, might be unnecessary to do both always
|
||||||
struct tile_state
|
struct tile_state
|
||||||
{
|
{
|
||||||
tile_info tiles[15];
|
tile_info tiles[15]{};
|
||||||
zcull_info zculls[8];
|
zcull_info zculls[8]{};
|
||||||
|
|
||||||
template<typename Archive>
|
template<typename Archive>
|
||||||
void serialize(Archive & ar)
|
void serialize(Archive & ar)
|
||||||
@ -126,7 +127,7 @@ namespace rsx
|
|||||||
|
|
||||||
struct display_buffers_state
|
struct display_buffers_state
|
||||||
{
|
{
|
||||||
std::array<buffer_state, 8> buffers;
|
std::array<buffer_state, 8> buffers{};
|
||||||
u32 count{0};
|
u32 count{0};
|
||||||
|
|
||||||
template<typename Archive>
|
template<typename Archive>
|
||||||
@ -195,12 +196,12 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
u64 tile_hash{0};
|
u64 tile_hash{0};
|
||||||
u64 display_buffer_hash{0};
|
u64 display_buffer_hash{0};
|
||||||
frame_capture_data::display_buffers_state buffer_state;
|
frame_capture_data::display_buffers_state buffer_state{};
|
||||||
frame_capture_data::tile_state tile_state;
|
frame_capture_data::tile_state tile_state{};
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 user_mem_addr;
|
u32 user_mem_addr{};
|
||||||
current_state cs;
|
current_state cs{};
|
||||||
std::unique_ptr<frame_capture_data> frame;
|
std::unique_ptr<frame_capture_data> frame;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -6,9 +6,10 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
struct shader_loading_dialog
|
struct shader_loading_dialog
|
||||||
{
|
{
|
||||||
std::shared_ptr<MsgDialogBase> dlg;
|
std::shared_ptr<MsgDialogBase> dlg{};
|
||||||
atomic_t<int> ref_cnt;
|
atomic_t<int> ref_cnt{0};
|
||||||
|
|
||||||
|
virtual ~shader_loading_dialog() = default;
|
||||||
virtual void create(const std::string& msg, const std::string& title);
|
virtual void create(const std::string& msg, const std::string& title);
|
||||||
virtual void update_msg(u32 index, const std::string& msg);
|
virtual void update_msg(u32 index, const std::string& msg);
|
||||||
virtual void inc_value(u32 index, u32 value);
|
virtual void inc_value(u32 index, u32 value);
|
||||||
|
@ -16,7 +16,7 @@ namespace rsx
|
|||||||
struct shader_loading_dialog_native : rsx::shader_loading_dialog
|
struct shader_loading_dialog_native : rsx::shader_loading_dialog
|
||||||
{
|
{
|
||||||
rsx::thread* owner = nullptr;
|
rsx::thread* owner = nullptr;
|
||||||
std::shared_ptr<rsx::overlays::message_dialog> dlg;
|
std::shared_ptr<rsx::overlays::message_dialog> dlg{};
|
||||||
|
|
||||||
shader_loading_dialog_native(GSRender* ptr);
|
shader_loading_dialog_native(GSRender* ptr);
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ struct RSXFragmentProgram
|
|||||||
struct data_storage_helper
|
struct data_storage_helper
|
||||||
{
|
{
|
||||||
void* data_ptr = nullptr;
|
void* data_ptr = nullptr;
|
||||||
std::vector<char> local_storage;
|
std::vector<char> local_storage{};
|
||||||
|
|
||||||
data_storage_helper() = default;
|
data_storage_helper() = default;
|
||||||
|
|
||||||
@ -292,7 +292,7 @@ struct RSXFragmentProgram
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} mutable data;
|
} mutable data{};
|
||||||
|
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
u32 ucode_length = 0;
|
u32 ucode_length = 0;
|
||||||
@ -305,7 +305,7 @@ struct RSXFragmentProgram
|
|||||||
u32 texture_dimensions = 0;
|
u32 texture_dimensions = 0;
|
||||||
u32 texcoord_control_mask = 0;
|
u32 texcoord_control_mask = 0;
|
||||||
|
|
||||||
float texture_scale[16][4];
|
float texture_scale[16][4]{};
|
||||||
|
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
@ -327,7 +327,6 @@ struct RSXFragmentProgram
|
|||||||
|
|
||||||
RSXFragmentProgram()
|
RSXFragmentProgram()
|
||||||
{
|
{
|
||||||
std::memset(texture_scale, 0, sizeof(float) * 16 * 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RSXFragmentProgram clone(const RSXFragmentProgram& prog)
|
static RSXFragmentProgram clone(const RSXFragmentProgram& prog)
|
||||||
|
@ -43,6 +43,9 @@ namespace rsx
|
|||||||
transport_packet(u32 command, void* args)
|
transport_packet(u32 command, void* args)
|
||||||
: type(op::callback), src(args), aux_param0(command)
|
: type(op::callback), src(args), aux_param0(command)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
transport_packet(const transport_packet&) = delete;
|
||||||
|
transport_packet& operator=(const transport_packet&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
atomic_t<bool> m_mem_fault_flag = false;
|
atomic_t<bool> m_mem_fault_flag = false;
|
||||||
|
@ -7,10 +7,15 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const u8 m_index;
|
const u8 m_index;
|
||||||
std::array<u32, 0x10000 / 4> ®isters;
|
std::array<u32, 0x10000 / 4>& registers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fragment_texture(u8 idx, std::array<u32, 0x10000 / 4> &r) : m_index(idx), registers(r) { }
|
fragment_texture(u8 idx, std::array<u32, 0x10000 / 4>& r)
|
||||||
|
: m_index(idx)
|
||||||
|
, registers(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
fragment_texture() = delete;
|
fragment_texture() = delete;
|
||||||
|
|
||||||
// Offset
|
// Offset
|
||||||
@ -87,10 +92,15 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
const u8 m_index;
|
const u8 m_index;
|
||||||
std::array<u32, 0x10000 / 4> ®isters;
|
std::array<u32, 0x10000 / 4>& registers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vertex_texture(u8 idx, std::array<u32, 0x10000 / 4> &r) : m_index(idx), registers(r) { }
|
vertex_texture(u8 idx, std::array<u32, 0x10000 / 4> &r)
|
||||||
|
: m_index(idx)
|
||||||
|
, registers(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
vertex_texture() = delete;
|
vertex_texture() = delete;
|
||||||
|
|
||||||
// Offset
|
// Offset
|
||||||
|
@ -40,12 +40,12 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
std::array<atomic_t<u32>, 4096> ea;
|
std::array<atomic_t<u32>, 4096> ea;
|
||||||
std::array<atomic_t<u32>, 4096> io;
|
std::array<atomic_t<u32>, 4096> io;
|
||||||
std::array<shared_mutex, 4096> rs;
|
std::array<shared_mutex, 4096> rs{};
|
||||||
|
|
||||||
rsx_iomap_table() noexcept
|
rsx_iomap_table() noexcept
|
||||||
|
: ea(fill_array(-1))
|
||||||
|
, io(fill_array(-1))
|
||||||
{
|
{
|
||||||
std::memset(ea.data(), -1, sizeof(ea));
|
|
||||||
std::memset(io.data(), -1, sizeof(io));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get the real address given a mapped address
|
// Try to get the real address given a mapped address
|
||||||
|
@ -63,16 +63,16 @@ namespace rsx
|
|||||||
class draw_clause
|
class draw_clause
|
||||||
{
|
{
|
||||||
// Stores the first and count argument from draw/draw indexed parameters between begin/end clauses.
|
// Stores the first and count argument from draw/draw indexed parameters between begin/end clauses.
|
||||||
simple_array<draw_range_t> draw_command_ranges;
|
simple_array<draw_range_t> draw_command_ranges{};
|
||||||
|
|
||||||
// Stores rasterization barriers for primitive types sensitive to adjacency
|
// Stores rasterization barriers for primitive types sensitive to adjacency
|
||||||
simple_array<barrier_t> draw_command_barriers;
|
simple_array<barrier_t> draw_command_barriers{};
|
||||||
|
|
||||||
// Counter used to parse the commands in order
|
// Counter used to parse the commands in order
|
||||||
u32 current_range_index;
|
u32 current_range_index{};
|
||||||
|
|
||||||
// Location of last execution barrier
|
// Location of last execution barrier
|
||||||
u32 last_execution_barrier_index;
|
u32 last_execution_barrier_index{};
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
// Add a new draw command
|
// Add a new draw command
|
||||||
@ -102,14 +102,14 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
primitive_type primitive;
|
primitive_type primitive{};
|
||||||
draw_command command;
|
draw_command command{};
|
||||||
|
|
||||||
bool is_immediate_draw; // Set if part of the draw is submitted via push registers
|
bool is_immediate_draw{}; // Set if part of the draw is submitted via push registers
|
||||||
bool is_disjoint_primitive; // Set if primitive type does not rely on adjacency information
|
bool is_disjoint_primitive{}; // Set if primitive type does not rely on adjacency information
|
||||||
bool primitive_barrier_enable; // Set once to signal that a primitive restart barrier can be inserted
|
bool primitive_barrier_enable{}; // Set once to signal that a primitive restart barrier can be inserted
|
||||||
|
|
||||||
simple_array<u32> inline_vertex_array;
|
simple_array<u32> inline_vertex_array{};
|
||||||
|
|
||||||
void insert_command_barrier(command_barrier_type type, u32 arg)
|
void insert_command_barrier(command_barrier_type type, u32 arg)
|
||||||
{
|
{
|
||||||
@ -457,8 +457,8 @@ namespace rsx
|
|||||||
struct rsx_state
|
struct rsx_state
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::array<u32, 0x10000 / 4> registers;
|
std::array<u32, 0x10000 / 4> registers{};
|
||||||
u32 register_previous_value;
|
u32 register_previous_value{};
|
||||||
|
|
||||||
template<u32 opcode>
|
template<u32 opcode>
|
||||||
using decoded_type = typename registers_decoder<opcode>::decoded_type;
|
using decoded_type = typename registers_decoder<opcode>::decoded_type;
|
||||||
@ -492,10 +492,10 @@ namespace rsx
|
|||||||
std::array<vertex_texture, 4> vertex_textures;
|
std::array<vertex_texture, 4> vertex_textures;
|
||||||
|
|
||||||
|
|
||||||
std::array<u32, 512 * 4> transform_program;
|
std::array<u32, 512 * 4> transform_program{};
|
||||||
std::array<u32[4], 512> transform_constants;
|
std::array<u32[4], 512> transform_constants{};
|
||||||
|
|
||||||
draw_clause current_draw_clause;
|
draw_clause current_draw_clause{};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSX can sources vertex attributes from 2 places:
|
* RSX can sources vertex attributes from 2 places:
|
||||||
@ -514,7 +514,7 @@ namespace rsx
|
|||||||
* Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask
|
* Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask
|
||||||
* request inputs is unknown.
|
* request inputs is unknown.
|
||||||
*/
|
*/
|
||||||
std::array<register_vertex_data_info, 16> register_vertex_info;
|
std::array<register_vertex_data_info, 16> register_vertex_info{};
|
||||||
std::array<data_array_format_info, 16> vertex_arrays_info;
|
std::array<data_array_format_info, 16> vertex_arrays_info;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -23,8 +23,8 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
data_array_format_info(int id, std::array<u32, 0x10000 / 4>& r)
|
data_array_format_info(int id, std::array<u32, 0x10000 / 4>& r)
|
||||||
: index(id)
|
: index(id)
|
||||||
, registers(r)
|
, registers(r)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ struct register_vertex_data_info
|
|||||||
vertex_base_type type = vertex_base_type::f;
|
vertex_base_type type = vertex_base_type::f;
|
||||||
|
|
||||||
register_vertex_data_info() = default;
|
register_vertex_data_info() = default;
|
||||||
std::array<u32, 4> data;
|
std::array<u32, 4> data{};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ else()
|
|||||||
#add_compile_options(-Wpadded)
|
#add_compile_options(-Wpadded)
|
||||||
add_compile_options(-Wempty-body)
|
add_compile_options(-Wempty-body)
|
||||||
add_compile_options(-Wredundant-decls)
|
add_compile_options(-Wredundant-decls)
|
||||||
|
#add_compile_options(-Weffc++)
|
||||||
|
|
||||||
add_compile_options(-Wstrict-aliasing=1)
|
add_compile_options(-Wstrict-aliasing=1)
|
||||||
#add_compile_options(-Wnull-dereference)
|
#add_compile_options(-Wnull-dereference)
|
||||||
|
@ -15,8 +15,8 @@ namespace stx
|
|||||||
// Save default constructor and destructor
|
// Save default constructor and destructor
|
||||||
struct typeinfo
|
struct typeinfo
|
||||||
{
|
{
|
||||||
bool(*create)(uchar* ptr, auto_typemap&) noexcept;
|
bool(*create)(uchar* ptr, auto_typemap&) noexcept = nullptr;
|
||||||
void(*destroy)(void* ptr) noexcept;
|
void(*destroy)(void* ptr) noexcept = nullptr;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool call_ctor(uchar* ptr, auto_typemap& _this) noexcept
|
static bool call_ctor(uchar* ptr, auto_typemap& _this) noexcept
|
||||||
|
@ -56,9 +56,9 @@ namespace stx
|
|||||||
// Save default constructor and destructor
|
// Save default constructor and destructor
|
||||||
struct typeinfo
|
struct typeinfo
|
||||||
{
|
{
|
||||||
bool(*create)(uchar* ptr, manual_typemap&) noexcept;
|
bool(*create)(uchar* ptr, manual_typemap&) noexcept = nullptr;
|
||||||
void(*destroy)(void* ptr) noexcept;
|
void(*destroy)(void* ptr) noexcept = nullptr;
|
||||||
std::string_view name;
|
std::string_view name{};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static bool call_ctor(uchar* ptr, manual_typemap& _this) noexcept
|
static bool call_ctor(uchar* ptr, manual_typemap& _this) noexcept
|
||||||
|
@ -113,7 +113,7 @@ namespace stx
|
|||||||
class alignas(T) shared_data final : align_filler<sizeof(shared_counter), alignof(T)>
|
class alignas(T) shared_data final : align_filler<sizeof(shared_counter), alignof(T)>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
shared_counter m_ctr;
|
shared_counter m_ctr{};
|
||||||
|
|
||||||
T m_data;
|
T m_data;
|
||||||
|
|
||||||
@ -128,9 +128,9 @@ namespace stx
|
|||||||
class alignas(T) shared_data<T[]> final : align_filler<sizeof(shared_counter) + sizeof(usz), alignof(T)>
|
class alignas(T) shared_data<T[]> final : align_filler<sizeof(shared_counter) + sizeof(usz), alignof(T)>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
usz m_count;
|
usz m_count{};
|
||||||
|
|
||||||
shared_counter m_ctr;
|
shared_counter m_ctr{};
|
||||||
|
|
||||||
constexpr shared_data() noexcept = default;
|
constexpr shared_data() noexcept = default;
|
||||||
};
|
};
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using std::chrono::steady_clock;
|
using std::chrono::steady_clock;
|
||||||
|
|
||||||
@ -457,16 +458,16 @@ constexpr inline struct umax_helper
|
|||||||
{
|
{
|
||||||
constexpr umax_helper() noexcept = default;
|
constexpr umax_helper() noexcept = default;
|
||||||
|
|
||||||
template <typename T, typename S = std::common_type_t<T>, typename = std::enable_if_t<std::is_unsigned_v<S>>>
|
template <typename T> requires (std::is_unsigned_v<std::common_type_t<T>>) || (std::is_same_v<std::common_type_t<T>, u128>)
|
||||||
constexpr bool operator==(const T& rhs) const
|
friend constexpr bool operator==(const umax_helper&, const T& rhs)
|
||||||
{
|
{
|
||||||
return rhs == static_cast<S>(-1);
|
return rhs == static_cast<std::common_type_t<T>>(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cpp_impl_three_way_comparison >= 201711 && !__INTELLISENSE__
|
#if __cpp_impl_three_way_comparison >= 201711 && !__INTELLISENSE__
|
||||||
#else
|
#else
|
||||||
template <typename T>
|
template <typename T> requires (std::is_unsigned_v<std::common_type_t<T>>) || (std::is_same_v<std::common_type_t<T>, u128>)
|
||||||
friend constexpr std::enable_if_t<std::is_unsigned_v<std::common_type_t<T>>, bool> operator==(const T& lhs, const umax_helper&)
|
friend constexpr bool operator==(const T& lhs, const umax_helper&)
|
||||||
{
|
{
|
||||||
return lhs == static_cast<std::common_type_t<T>>(-1);
|
return lhs == static_cast<std::common_type_t<T>>(-1);
|
||||||
}
|
}
|
||||||
@ -474,14 +475,14 @@ constexpr inline struct umax_helper
|
|||||||
|
|
||||||
#if __cpp_impl_three_way_comparison >= 201711
|
#if __cpp_impl_three_way_comparison >= 201711
|
||||||
#else
|
#else
|
||||||
template <typename T, typename S = std::common_type_t<T>, typename = std::enable_if_t<std::is_unsigned_v<S>>>
|
template <typename T> requires (std::is_unsigned_v<std::common_type_t<T>>) || (std::is_same_v<std::common_type_t<T>, u128>)
|
||||||
constexpr bool operator!=(const T& rhs) const
|
friend constexpr bool operator!=(const umax_helper&, const T& rhs)
|
||||||
{
|
{
|
||||||
return rhs != static_cast<S>(-1);
|
return rhs != static_cast<std::common_type_t<T>>(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> requires (std::is_unsigned_v<std::common_type_t<T>>) || (std::is_same_v<std::common_type_t<T>, u128>)
|
||||||
friend constexpr std::enable_if_t<std::is_unsigned_v<std::common_type_t<T>>, bool> operator!=(const T& lhs, const umax_helper&)
|
friend constexpr bool operator!=(const T& lhs, const umax_helper&)
|
||||||
{
|
{
|
||||||
return lhs != static_cast<std::common_type_t<T>>(-1);
|
return lhs != static_cast<std::common_type_t<T>>(-1);
|
||||||
}
|
}
|
||||||
@ -767,3 +768,33 @@ struct value_hash
|
|||||||
return static_cast<usz>(value) >> Shift;
|
return static_cast<usz>(value) >> Shift;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
struct fill_array_t
|
||||||
|
{
|
||||||
|
std::tuple<T...> args;
|
||||||
|
|
||||||
|
template <typename V, usz Num>
|
||||||
|
constexpr std::unwrap_reference_t<V> get() const
|
||||||
|
{
|
||||||
|
return std::get<Num>(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U, usz N, usz... M, usz... Idx>
|
||||||
|
constexpr std::array<U, N> fill(std::index_sequence<M...>, std::index_sequence<Idx...>) const
|
||||||
|
{
|
||||||
|
return{(static_cast<void>(Idx), U(get<T, M>()...))...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U, usz N>
|
||||||
|
constexpr operator std::array<U, N>() const
|
||||||
|
{
|
||||||
|
return fill<U, N>(std::make_index_sequence<sizeof...(T)>(), std::make_index_sequence<N>());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
constexpr auto fill_array(const T&... args)
|
||||||
|
{
|
||||||
|
return fill_array_t<T...>{{args...}};
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user