OpenSiv3D icon indicating copy to clipboard operation
OpenSiv3D copied to clipboard

Array の推論補助の追加、改良

Open Raclamusi opened this issue 2 years ago • 4 comments

Array の推論補助について、下の5点を提案します。

  • Array(std::initializer_list<Type>, const Allocator&) に対する推論補助を追加
  • Array(const ArrayIsh& a)Array(ArrayIsh&&) に変更して引数を右辺値参照で受け取る場合に対応
  • decltype(std::declval<ArrayIsh>().asArray())std::remove_cvref_t<decltype(…)> に変更して asArray() の戻り値が参照である場合に対応
  • Array(ArrayIsh&&) -> Array<…::value_type>Array(ArrayIsh&&) -> Array<…::value_type, …::allocator_type> に変更して asArray() の戻り値の allocator_typestd::allocator<value_type> でない場合に対応
  • Array(Iterator, Iterator)Array(Iterator, Iterator, const Allocator&) に対する推論補助を追加
# include <Siv3D.hpp> // OpenSiv3D v0.6.5

namespace s3d
{
	// ==========
	// Array.hpp
	// ==========
/*
	// deduction guide
	template <class Type>
	Array(std::initializer_list<Type>)->Array<Type>;

	template <class ArrayIsh, std::enable_if_t<Meta::HasAsArray<ArrayIsh>::value>* = nullptr>
	Array(const ArrayIsh& a)->Array<typename decltype(std::declval<ArrayIsh>().asArray())::value_type>;
*/
	// deduction guide
	template <class Type, class Allocator = std::allocator<Type>>
	Array(std::initializer_list<Type>, const Allocator& = Allocator{}) -> Array<Type, Allocator>;

	template <class ArrayIsh, std::enable_if_t<Meta::HasAsArray<ArrayIsh>::value>* = nullptr>
	Array(ArrayIsh&&) -> Array<typename std::remove_cvref_t<decltype(std::declval<ArrayIsh>().asArray())>::value_type, typename std::remove_cvref_t<decltype(std::declval<ArrayIsh>().asArray())>::allocator_type>;

	template <class Iterator, class Allocator = std::allocator<typename std::iterator_traits<Iterator>::value_type>>
	Array(Iterator, Iterator, const Allocator& = Allocator{}) -> Array<typename std::iterator_traits<Iterator>::value_type, Allocator>;
}


struct AllocatorDeductionTest
{
	Array<char, std::pmr::polymorphic_allocator<char>> asArray() const
	{
		return { 'p', 'm', 'r' };
	}
};

void Main()
{
	std::list<int, std::pmr::polymorphic_allocator<int>> list{ 3, 1, 4, 1, 5, 9 };

	Array array1({ 2, 7, 1, 8, 2, 8 }, std::allocator<int>{});
	Array array2(LineString{ Vec2{ 0, 5 }, Vec2{ 3, 0 }, Vec2{ -3, 0 } });
	Array array3(AllocatorDeductionTest{});
	Array array4(list.begin(), list.end());

	Print << array1;
	Print << array2;
	Print << array3;
	Print << array4;

	while (System::Update());
}

Raclamusi avatar Sep 07 '22 15:09 Raclamusi

網羅的な提案で助かります! v0.6.6 で作業します。

Reputeless avatar Sep 07 '22 15:09 Reputeless

@Raclamusi さん、本 Issue について pull-request 投げてくれれば、こちらで確認して問題なさそうならマージします。

Reputeless avatar Sep 08 '22 09:09 Reputeless

pull-request 投げました。ご確認、お願いします。

Raclamusi avatar Sep 08 '22 11:09 Raclamusi

開発中の v0.6.6 において、#890 で対応完了。

# include <Siv3D.hpp>

struct AllocatorDeductionTest
{
	Array<char, std::pmr::polymorphic_allocator<char>> asArray() const
	{
		return { 'p', 'm', 'r' };
	}
};

void Main()
{
	Array v1({ 1, 2, 3, 4, 5 });
	Array v2({ 1, 2, 3, 4, 5 }, std::allocator<int32>{});
	Array v3(LineString{ Vec2{ 1, 2 }, Vec2{ 3, 4 }, Vec2{ 5, 6 } });
	Array v4(AllocatorDeductionTest{});

	std::list<int32, std::pmr::polymorphic_allocator<int32>> list{ 1, 2, 3, 4, 5 };
	Array v5(list.begin(), list.end());

	Print << v1;
	Print << v2;
	Print << v3;
	Print << v4;
	Print << v5;

	while (System::Update())
	{

	}
}

Reputeless avatar Sep 08 '22 13:09 Reputeless