From e7eac8daa78d3a940d3959f95ce3083a8797725c Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Sun, 13 Jun 2021 20:57:15 +0300 Subject: [PATCH 1/8] Variant solution --- module-1/homework/Variant/variant.h | 193 +++++++++++++++++++++++++--- 1 file changed, 178 insertions(+), 15 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index 647742e7..0a33d837 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -5,7 +5,144 @@ namespace task { -template +template +struct TypeList { + using head = Head; + using tail = TypeList; +}; + +template +struct TypeAt; + +template +struct TypeAt<0, TypeList> { + using result = Head; +}; + +template +struct TypeAt> { + using result = typename TypeAt>::result; +}; + +template +struct InPlaceIndex { + explicit InPlaceIndex() = default; +}; + +template +constexpr InPlaceIndex kInPlaceIndex{}; + +template +union Union; + +template +union Union {}; + +template +union Union { +public: + Union() : tail() { + if (!std::is_trivially_constructible_v) { + new (&head) T(); + } + } + + ~Union() { + if (!std::is_trivially_destructible_v) { + head.~T(); + } + } + +public: + T head; + Union tail; + + friend struct UnionHelper; +}; + + +struct UnionHelper { + template + static constexpr auto&& GetAlt(U&& v, InPlaceIndex<0>) { + return std::forward(v).head; + } + + template + static constexpr auto&& GetAlt(U&& v, InPlaceIndex) { + return GetAlt(std::forward(v).tail, kInPlaceIndex); + } +}; + +struct VariantHelper { + template + static constexpr auto&& GetAlt(T&& v) { + return UnionHelper::GetAlt(std::forward(v).data_, kInPlaceIndex); + } +}; + +struct AssignUnion { + template + static void AssignHelper(U&& value, InPlaceIndex<0>, Union& u) { + u.head = value; + } + + template + static void AssignHelper(U&& value, InPlaceIndex, Union& u) { + AssignUnion::AssignHelper(std::forward(value), kInPlaceIndex, u.tail); + } +}; + + +const static std::size_t kNotFound = -1; +const static std::size_t kAmbiguity = kNotFound - 1; + +constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool* found, const bool* found_convertible) { + if (res == kAmbiguity) { + return res; + } + + if (found[i]) { + if (res == kNotFound || !(!found[res] && found_convertible[res])) { + return i; + } + return kAmbiguity; + } + + if (res == kNotFound && found_convertible[i]) { + return i; + } + + return res; +} + +template +constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[SizeofFound], const bool (&convertible)[SizeofFound]) { + if (currnet == SizeofFound) { + return kNotFound; + } + return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, convertible); +} + +template +struct FindExactlyOneChecked { + constexpr static bool kFound[sizeof...(Type)] = {std::is_same::value...}; + constexpr static bool kFoundConvertible[sizeof...(Type)] = { + std::is_convertible::value...}; + constexpr static std::size_t kValue = ProcessForward(0, kFound, kFoundConvertible); + + static_assert(kValue != kNotFound); + static_assert(kValue != kAmbiguity); +}; + +template +struct FindExactlyOneChecked { + static_assert(!std::is_same::value); +}; + +template +struct FindExactlyOne : public FindExactlyOneChecked {}; + +template class Variant; template @@ -14,35 +151,61 @@ struct VariantAlternative; template using variant_alternative_t = typename VariantAlternative::type; -template -struct VariantAlternative> { - using type = // Your code goes here +template +struct VariantAlternative> { + using type = typename TypeAt>::result; }; -template +template class Variant { public: // Special member functions constexpr Variant() noexcept; - template + template ::kValue> Variant& operator=(T&& t) noexcept; private: - // Your code goes here + Union<0, Type...> data_; + + friend VariantHelper; }; +template +constexpr Variant::Variant() noexcept { +} + +template +template +Variant& Variant::operator=(T&& t) noexcept { + AssignUnion::AssignHelper(std::forward(t), kInPlaceIndex, data_); + return *this; +} + +template +auto&& GenericGet(T&& v) { + return VariantHelper::GetAlt(std::forward(v)); +} + // Non-member functions -template -constexpr const variant_alternative_t>& Get(Variant& v); +template +constexpr const variant_alternative_t>& Get(Variant& v) { + return GenericGet(v); +} -template -constexpr variant_alternative_t>&& Get(Variant&& v); +template +constexpr variant_alternative_t>&& Get(Variant&& v) { + return GenericGet(v); +} -template -constexpr const T& Get(Variant& v); +template +constexpr const T& Get(Variant& v) { + return GenericGet::kValue>(v); +} -template -constexpr T&& Get(Variant&& v); +template +constexpr T&& Get(Variant&& v) { + return GenericGet::kValue>(v); +} }; // namespace task \ No newline at end of file From 26954bddebf02ef2e49adb66437639a8a589ba67 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Sun, 13 Jun 2021 22:43:11 +0300 Subject: [PATCH 2/8] fix clang format 1.0 --- module-1/homework/Variant/variant.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index 0a33d837..e7f231d1 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -60,7 +60,6 @@ union Union { friend struct UnionHelper; }; - struct UnionHelper { template static constexpr auto&& GetAlt(U&& v, InPlaceIndex<0>) { @@ -92,11 +91,11 @@ struct AssignUnion { } }; - const static std::size_t kNotFound = -1; const static std::size_t kAmbiguity = kNotFound - 1; -constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool* found, const bool* found_convertible) { +constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool* found, + const bool* found_convertible) { if (res == kAmbiguity) { return res; } @@ -116,11 +115,13 @@ constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool } template -constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[SizeofFound], const bool (&convertible)[SizeofFound]) { +constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[SizeofFound], + const bool (&convertible)[SizeofFound]) { if (currnet == SizeofFound) { return kNotFound; } - return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, convertible); + return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, + convertible); } template From 9a682cb09073f2efef4f3f7ab7e4bbe55ed5d4cb Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Sun, 13 Jun 2021 22:47:46 +0300 Subject: [PATCH 3/8] fix clang format 1.1 --- module-1/homework/Variant/variant.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index e7f231d1..a5cc6caa 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -95,7 +95,7 @@ const static std::size_t kNotFound = -1; const static std::size_t kAmbiguity = kNotFound - 1; constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool* found, - const bool* found_convertible) { + const bool* found_convertible) { if (res == kAmbiguity) { return res; } @@ -116,12 +116,12 @@ constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool template constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[SizeofFound], - const bool (&convertible)[SizeofFound]) { + const bool (&convertible)[SizeofFound]) { if (currnet == SizeofFound) { return kNotFound; } return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, - convertible); + convertible); } template From fe169625e840394420436b13d06ff8bde857e4c0 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Sun, 13 Jun 2021 22:50:19 +0300 Subject: [PATCH 4/8] fix clang format 1.2 --- module-1/homework/Variant/variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index a5cc6caa..6a34c862 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -120,7 +120,7 @@ constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[Si if (currnet == SizeofFound) { return kNotFound; } - return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, + return ProcessBackward(currnet, ProcessForward(currnet + 1, found, convertible), found, convertible); } From 76b4ff113808c64d3d39300175b4e2e701cf51a8 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 13:58:03 +0300 Subject: [PATCH 5/8] fixed size_t --- module-1/homework/Variant/variant.h | 36 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index 6a34c862..fe424c0a 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -24,21 +24,21 @@ struct TypeAt> { using result = typename TypeAt>::result; }; -template +template struct InPlaceIndex { explicit InPlaceIndex() = default; }; -template +template constexpr InPlaceIndex kInPlaceIndex{}; -template +template union Union; -template +template union Union {}; -template +template union Union { public: Union() : tail() { @@ -66,35 +66,35 @@ struct UnionHelper { return std::forward(v).head; } - template + template static constexpr auto&& GetAlt(U&& v, InPlaceIndex) { return GetAlt(std::forward(v).tail, kInPlaceIndex); } }; struct VariantHelper { - template + template static constexpr auto&& GetAlt(T&& v) { return UnionHelper::GetAlt(std::forward(v).data_, kInPlaceIndex); } }; struct AssignUnion { - template + template static void AssignHelper(U&& value, InPlaceIndex<0>, Union& u) { u.head = value; } - template + template static void AssignHelper(U&& value, InPlaceIndex, Union& u) { AssignUnion::AssignHelper(std::forward(value), kInPlaceIndex, u.tail); } }; -const static std::size_t kNotFound = -1; -const static std::size_t kAmbiguity = kNotFound - 1; +const static size_t kNotFound{-1}; +const static size_t kAmbiguity{kNotFound - 1}; -constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool* found, +constexpr size_t ProcessBackward(size_t i, size_t res, const bool* found, const bool* found_convertible) { if (res == kAmbiguity) { return res; @@ -114,8 +114,8 @@ constexpr std::size_t ProcessBackward(std::size_t i, std::size_t res, const bool return res; } -template -constexpr std::size_t ProcessForward(std::size_t currnet, const bool (&found)[SizeofFound], +template +constexpr size_t ProcessForward(size_t currnet, const bool (&found)[SizeofFound], const bool (&convertible)[SizeofFound]) { if (currnet == SizeofFound) { return kNotFound; @@ -129,7 +129,7 @@ struct FindExactlyOneChecked { constexpr static bool kFound[sizeof...(Type)] = {std::is_same::value...}; constexpr static bool kFoundConvertible[sizeof...(Type)] = { std::is_convertible::value...}; - constexpr static std::size_t kValue = ProcessForward(0, kFound, kFoundConvertible); + constexpr static size_t kValue = ProcessForward(0, kFound, kFoundConvertible); static_assert(kValue != kNotFound); static_assert(kValue != kAmbiguity); @@ -163,7 +163,7 @@ class Variant { // Special member functions constexpr Variant() noexcept; - template ::kValue> + template ::kValue> Variant& operator=(T&& t) noexcept; private: @@ -177,13 +177,13 @@ constexpr Variant::Variant() noexcept { } template -template +template Variant& Variant::operator=(T&& t) noexcept { AssignUnion::AssignHelper(std::forward(t), kInPlaceIndex, data_); return *this; } -template +template auto&& GenericGet(T&& v) { return VariantHelper::GetAlt(std::forward(v)); } From 8e8287301dbd3a1111d05c5809f859e579556b18 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 14:01:59 +0300 Subject: [PATCH 6/8] fixed size_t 2.0 --- module-1/homework/Variant/variant.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index fe424c0a..95537872 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -91,8 +91,8 @@ struct AssignUnion { } }; -const static size_t kNotFound{-1}; -const static size_t kAmbiguity{kNotFound - 1}; +const static int16_t kNotFound{-1}; +const static int16_t kAmbiguity{kNotFound - 1}; constexpr size_t ProcessBackward(size_t i, size_t res, const bool* found, const bool* found_convertible) { From bac2ab57c9e06ba8244c160759952f5d60527ef0 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 14:05:22 +0300 Subject: [PATCH 7/8] fixed size_t 2.0 --- module-1/homework/Variant/variant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index 95537872..ef20ba0f 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -94,7 +94,7 @@ struct AssignUnion { const static int16_t kNotFound{-1}; const static int16_t kAmbiguity{kNotFound - 1}; -constexpr size_t ProcessBackward(size_t i, size_t res, const bool* found, +constexpr size_t ProcessBackward(size_t i, int16_t res, const bool* found, const bool* found_convertible) { if (res == kAmbiguity) { return res; From 399f99aff618b7fd192fbf28ea90143c26be4e97 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Mon, 14 Jun 2021 14:07:59 +0300 Subject: [PATCH 8/8] fixed size_t 2.2 --- module-1/homework/Variant/variant.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module-1/homework/Variant/variant.h b/module-1/homework/Variant/variant.h index ef20ba0f..f073fb2d 100644 --- a/module-1/homework/Variant/variant.h +++ b/module-1/homework/Variant/variant.h @@ -95,7 +95,7 @@ const static int16_t kNotFound{-1}; const static int16_t kAmbiguity{kNotFound - 1}; constexpr size_t ProcessBackward(size_t i, int16_t res, const bool* found, - const bool* found_convertible) { + const bool* found_convertible) { if (res == kAmbiguity) { return res; } @@ -116,7 +116,7 @@ constexpr size_t ProcessBackward(size_t i, int16_t res, const bool* found, template constexpr size_t ProcessForward(size_t currnet, const bool (&found)[SizeofFound], - const bool (&convertible)[SizeofFound]) { + const bool (&convertible)[SizeofFound]) { if (currnet == SizeofFound) { return kNotFound; }