pinned: Add class for memory pinning
This makes it possible to trivially specify that we want persistent
memory references to objects.
Change-Id: I469caa08c36299cba16de389714a398f9386ee6e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/pinned.cpp b/test/pinned.cpp
new file mode 100644
index 0000000..c8daa3c
--- /dev/null
+++ b/test/pinned.cpp
@@ -0,0 +1,107 @@
+#include <gtest/gtest.h>
+#include <memory>
+#include <stdplus/pinned.hpp>
+#include <string>
+
+namespace stdplus
+{
+
+static_assert(noexcept(Pinned<int>(4)));
+static_assert(!noexcept(Pinned<std::string>("4")));
+
+TEST(Pinned, Basic)
+{
+ EXPECT_EQ("hi", Pinned<std::string>("hi"));
+ EXPECT_EQ("hi", Pinned<std::string>(std::string("hi")));
+ auto s = std::string("hi");
+ EXPECT_EQ("hi", Pinned<std::string>(s));
+ EXPECT_EQ("hi", Pinned<std::string>(std::move(s)));
+ Pinned<std::string> ps = "hi";
+ EXPECT_EQ("hi", Pinned<std::string>(ps));
+ // EXPECT_EQ("hi", Pinned<std::string>(std::move(ps)));
+ ps = "hi";
+ EXPECT_EQ("hi", ps);
+ s = std::string("hi");
+ ps = s;
+ EXPECT_EQ("hi", ps);
+ ps = std::move(s);
+ EXPECT_EQ("hi", ps);
+ Pinned<std::string> ps2;
+ ps2 = ps;
+ EXPECT_EQ("hi", ps2);
+ // ps2 = std::move(ps);
+ // std::string s2 = std::move(ps2);
+ EXPECT_EQ("hi", [](std::string& f) { return f; }(ps2));
+ EXPECT_EQ("hi", [](std::string f) { return f; }(ps2));
+}
+
+TEST(Pinned, Fundamental)
+{
+ Pinned<int> pi = 4;
+ EXPECT_EQ(4, [](int& f) { return f; }(pi));
+ EXPECT_EQ(4, [](int f) { return f; }(pi));
+}
+
+struct NoMove1
+{
+ NoMove1() = default;
+ NoMove1(NoMove1&&) = delete;
+ NoMove1& operator=(NoMove1&&) = default;
+};
+
+struct NoMove2
+{
+ NoMove2() = default;
+ NoMove2(NoMove2&&) = default;
+ NoMove2& operator=(NoMove2&&) = delete;
+};
+
+struct NoMove3
+{
+ NoMove3() = default;
+ NoMove3(NoMove3&&) = delete;
+ NoMove3& operator=(NoMove3&&) = delete;
+};
+
+TEST(PinnedRef, Basic)
+{
+ auto uptr = std::make_unique<std::string>("hi");
+ PinnedRef<std::string>(uptr).get()[0] = 'd';
+ EXPECT_EQ("di", *uptr);
+ PinnedRef<const std::string> cref(uptr);
+ // cref.get()[0] = 'e';
+ EXPECT_EQ("di", cref.get());
+
+ auto sptr = std::make_shared<std::string>("hi");
+ EXPECT_EQ("hi", PinnedRef<std::string>(sptr).get());
+
+ Pinned<std::string> pstr("hi");
+ EXPECT_EQ("hi", PinnedRef<std::string>(pstr).get());
+ EXPECT_EQ("hi", PinnedRef<const std::string>(pstr).get());
+ const Pinned<std::string> cpstr("hi");
+ // EXPECT_EQ("hi", PinnedRef<std::string>(cpstr).get());
+ EXPECT_EQ("hi", PinnedRef<const std::string>(cpstr).get());
+}
+
+TEST(PinnedRef, Fundamental)
+{
+ auto uptr = std::make_unique<int>(4);
+ EXPECT_EQ(4, PinnedRef<int>(uptr));
+ Pinned<int> pi = 4;
+ EXPECT_EQ(4, PinnedRef<int>(pi));
+ EXPECT_EQ(4, PinnedRef<const int>(pi));
+}
+
+TEST(PinnedREf, NoMove)
+{
+ // int i;
+ // PinnedRef<int> ri(i);
+ // NoMove1 nm1;
+ // PinnedRef<NoMove1> rnm1(nm1);
+ // NoMove2 nm2;
+ // PinnedRef<NoMove2> rnm2(nm2);
+ NoMove3 nm3;
+ PinnedRef<NoMove3> rnm3(nm3);
+}
+
+} // namespace stdplus