/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "test_global.hpp" #include #include using namespace orcus; void test_basic() { const char* static_text = "test"; string_pool pool; assert(pool.size() == 0); std::pair ret = pool.intern("foo"); assert(ret.first == "foo"); assert(ret.second); // new instance ret = pool.intern("foo"); assert(ret.first == "foo"); assert(!ret.second); // existing instance. // Empty strings should not be interned. ret = pool.intern(""); assert(ret.first.empty()); assert(!ret.second); ret = pool.intern("A"); std::cout << "interned string: " << ret.first << std::endl; assert(ret.second); assert(pool.size() == 2); // Duplicate string. ret = pool.intern("A"); std::cout << "interned string: " << ret.first << std::endl; assert(!ret.second); ret = pool.intern("B"); std::cout << "interned string: " << ret.first << std::endl; assert(pool.size() == 3); // Interning an already-intern string should return a string_view with // identical memory address. std::string_view str = ret.first; std::string_view str2 = pool.intern(str).first; assert(str == str2); assert(pool.size() == 3); assert(str.data() == str2.data()); // their memory address should be identical. std::string_view static_str(static_text); ret = pool.intern(static_str); str = ret.first; std::cout << "interned string: " << str << std::endl; assert(pool.size() == 4); assert(str == static_str); assert(str.data() != static_str.data()); // Make sure that the pool remains usable after calling clear(). pool.clear(); assert(pool.size() == 0); ret = pool.intern(static_str); assert(ret.second); // it should be a new string assert(ret.first == static_str); } void test_merge() { string_pool pool1; std::unique_ptr pool2(std::make_unique()); pool1.intern("A"); pool1.intern("B"); pool1.intern("C"); std::string_view v1 = pool1.intern("same value").first; pool2->intern("D"); pool2->intern("E"); pool2->intern("F"); std::string_view v2 = pool2->intern("same value").first; assert(pool1.size() == 4); assert(pool2->size() == 4); pool1.merge(*pool2); assert(pool1.size() == 7); assert(pool2->size() == 0); pool2.reset(); // Delete the pool2 instance altogether. // This should not create a new entry. auto r = pool1.intern("F"); assert(!r.second); // v2 still points to the original string in pool2, which should now be in // the merged store in pool1 (thus valid). assert(v1 == v2); std::vector entries = pool1.get_interned_strings(); assert(entries.size() == pool1.size()); } void test_move() { static_assert(!std::is_copy_constructible_v); static_assert(std::is_move_constructible_v); string_pool pool1; pool1.intern("A"); pool1.intern("B"); pool1.intern("C"); pool1.intern("D"); pool1.intern("E"); string_pool pool2 = std::move(pool1); assert(pool2.size() == 5); } int main() { test_basic(); test_merge(); test_move(); return EXIT_SUCCESS; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */