diff --git a/autotest/Moveable/Etalon.log b/autotest/Moveable/Etalon.log new file mode 100644 index 000000000..6a0958b11 --- /dev/null +++ b/autotest/Moveable/Etalon.log @@ -0,0 +1,16 @@ +* C:\upp\out\Core2024_autotest\CLANGx64.Debug.Debug_Full\Moveable.exe 23.08.2024 11:33:48, user: cxl + +h = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +h = [0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +======================= +h = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +h = [0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] +h = [0, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +h = [0, 4, 21, 22, 23, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +h = [0, 4, 21, 22, 23, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19] +x = [one, two, three] +x.Find("two") = 1 diff --git a/autotest/Moveable/Moveable.cpp b/autotest/Moveable/Moveable.cpp new file mode 100644 index 000000000..99c1737c8 --- /dev/null +++ b/autotest/Moveable/Moveable.cpp @@ -0,0 +1,66 @@ +#include + +using namespace Upp; + + +namespace Upp { + +//template <> +//inline constexpr bool is_upp_guest = true; + +}; + +template <> +inline constexpr bool Upp::is_upp_guest = true; + +template<> inline hash_t Upp::GetHashValue(const std::string& a) +{ + return memhash(a.data(), a.length()); +} + + +CONSOLE_APP_MAIN +{ + { + Vector h; + for(int i = 0; i < 20; i++) + h << AsString(i); + RDUMP(h); + Vector rem = { 1, 2, 3 }; + h.Remove(rem); + RDUMP(h); + h.RemoveIf([&](int i) { return h[i].EndsWith("8"); }); + RDUMP(h); + Vector n = { "21", "22", "23" }; + h.Insert(2, pick(n)); + RDUMP(h); + h.Remove(2, 3); + RDUMP(h); + } + RLOG("======================="); + { + Vector h; + for(int i = 0; i < 20; i++) + h << AsString(i).ToStd(); + RDUMP(h); + Vector rem = { 1, 2, 3 }; + h.Remove(rem); + RDUMP(h); + h.RemoveIf([&](int i) { return h[i].back() == '8'; }); + RDUMP(h); + Vector n = { "21", "22", "23" }; + h.Insert(2, n); + RDUMP(h); + h.Insert(2, pick(n)); + RDUMP(h); + h.Remove(2, 3); + RDUMP(h); + } + { + Index x { "one", "two", "three" }; + RDUMP(x); + RDUMP(x.Find("two")); + } + + CheckLogEtalon(); +} diff --git a/autotest/Moveable/Moveable.upp b/autotest/Moveable/Moveable.upp new file mode 100644 index 000000000..7e188889c --- /dev/null +++ b/autotest/Moveable/Moveable.upp @@ -0,0 +1,10 @@ +uses + Core; + +file + Etalon.log, + Moveable.cpp; + +mainconfig + "" = ""; + diff --git a/uppsrc/Core/Tuple.h b/uppsrc/Core/Tuple.h index e56db6032..50817390a 100644 --- a/uppsrc/Core/Tuple.h +++ b/uppsrc/Core/Tuple.h @@ -14,6 +14,8 @@ template struct TupleN<1, A> { A a; + + using T1 = A; bool operator==(const TupleN& x) const { return a == x.a; } int Compare(const TupleN& x) const { return SgnCompare(a, x.a); } @@ -56,6 +58,8 @@ template struct TupleN<2, A, B> : public TupleN<1, A> { typedef TupleN<1, A> Base; B b; + + using T2 = B; TUPLE_N_METHODS(b, 1); @@ -71,6 +75,8 @@ struct TupleN<3, A, B, C> : public TupleN<2, A, B> typedef TupleN<2, A, B> Base; C c; + using T3 = C; + TUPLE_N_METHODS(c, 2); TupleN(const A& a, const B& b, const C& c) : Base(a, b), c(c) {} @@ -85,6 +91,8 @@ struct TupleN<4, A, B, C, D> : public TupleN<3, A, B, C> typedef TupleN<3, A, B, C> Base; D d; + using T4 = D; + TUPLE_N_METHODS(d, 3); TupleN(const A& a, const B& b, const C& c, const D& d) : Base(a, b, c), d(d) {} @@ -118,13 +126,16 @@ struct Tuple : public TupleN { private: typedef TupleN Base; - friend void AssertMoveable0(Tuple *) {} - public: template const auto& Get() const { return GetFromTuple(*this, IndexI__()); } template auto& Get() { return GetFromTuple(*this, IndexI__()); } + + template // std compatibility & C++17 structured binding support + const auto& get() const { return GetFromTuple(*this, IndexI__()); } + template // std compatibility & C++17 structured binding support + auto& get() { return GetFromTuple(*this, IndexI__()); } template const T& Get() const { return GetFromTupleByType(*this, (T*)NULL); } template T& Get() { return GetFromTupleByType(*this, (T*)NULL); } @@ -227,6 +238,25 @@ struct Tie4 { template Tie4 Tie(A& a, B& b, C& c, D& d) { return Tie4(a, b, c, d); } +}; // end Upp namespace + +template + struct std::tuple_element<0, Upp::Tuple> { using type = typename Upp::Tuple::T1; }; + +template + struct std::tuple_element<1, Upp::Tuple> { using type = typename Upp::Tuple::T2; }; + +template + struct std::tuple_element<2, Upp::Tuple> { using type = typename Upp::Tuple::T3; }; + +template + struct std::tuple_element<3, Upp::Tuple> { using type = typename Upp::Tuple::T4; }; + +template + struct std::tuple_size> { static const int value = sizeof...(Args); }; + +namespace Upp { + // Backward compatibility template using Tuple2 = Tuple;