Browse Source

compressed_pair: added support for structured binding (with tests)

Michele Caini 4 years ago
parent
commit
ed2c714419
2 changed files with 75 additions and 0 deletions
  1. 38 0
      src/entt/core/compressed_pair.hpp
  2. 37 0
      test/entt/core/compressed_pair.cpp

+ 38 - 0
src/entt/core/compressed_pair.hpp

@@ -209,6 +209,33 @@ public:
         swap(first(), other.first());
         swap(second(), other.second());
     }
+
+    /**
+     * @brief Extracts an element from the compressed pair.
+     * @tparam Index An integer value that is either 0 or 1.
+     * @return Returns a reference to the first element if `Index` is 0 and a
+     * reference to the second element if `Index` is 1.
+     */
+    template<std::size_t Index>
+    decltype(auto) get() ENTT_NOEXCEPT {
+        if constexpr(Index == 0u) {
+            return first();
+        } else {
+            static_assert(Index == 1u, "Index out of bounds");
+            return second();
+        }
+    }
+
+    /*! @copydoc get */
+    template<std::size_t Index>
+    decltype(auto) get() const ENTT_NOEXCEPT {
+        if constexpr(Index == 0u) {
+            return first();
+        } else {
+            static_assert(Index == 1u, "Index out of bounds");
+            return second();
+        }
+    }
 };
 
 
@@ -238,4 +265,15 @@ inline void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Sec
 }
 
 
+namespace std {
+    template<typename First, typename Second>
+    struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
+
+    template<size_t Index, typename First, typename Second>
+    struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
+        static_assert(Index < 2u, "Index out of bounds");
+    };
+}
+
+
 #endif

+ 37 - 0
test/entt/core/compressed_pair.cpp

@@ -130,3 +130,40 @@ TEST(CompressedPair, Swap) {
     ASSERT_EQ(other.first(), 3);
     ASSERT_EQ(other.second(), 4);
 }
+
+TEST(CompressedPair, Get) {
+    entt::compressed_pair pair{1, 2};
+
+    ASSERT_EQ(pair.get<0>(), 1);
+    ASSERT_EQ(pair.get<1>(), 2);
+
+    ASSERT_EQ(&pair.get<0>(), &pair.first());
+    ASSERT_EQ(&pair.get<1>(), &pair.second());
+
+    auto &&[first, second] = pair;
+
+    ASSERT_EQ(first, 1);
+    ASSERT_EQ(second, 2);
+
+    first = 3;
+    second = 4;
+
+    ASSERT_EQ(pair.first(), 3);
+    ASSERT_EQ(pair.second(), 4);
+
+    auto &[cfirst, csecond] = std::as_const(pair);
+
+    ASSERT_EQ(cfirst, 3);
+    ASSERT_EQ(csecond, 4);
+
+    static_assert(std::is_same_v<decltype(cfirst), const int>);
+    static_assert(std::is_same_v<decltype(csecond), const int>);
+
+    auto [tfirst, tsecond] = entt::compressed_pair{9, 99};
+
+    ASSERT_EQ(tfirst, 9);
+    ASSERT_EQ(tsecond, 99);
+
+    static_assert(std::is_same_v<decltype(cfirst), const int>);
+    static_assert(std::is_same_v<decltype(csecond), const int>);
+}