diff options
| author | Stefan Boberg <[email protected]> | 2025-11-07 14:49:13 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-11-07 14:49:13 +0100 |
| commit | 24e43a913f29ac3b314354e8ce5175f135bcc64f (patch) | |
| tree | ca442937ceeb63461012b33a4576e9835099f106 /thirdparty/ryml/test/test_stack.cpp | |
| parent | get oplog attachments (#622) (diff) | |
| download | zen-24e43a913f29ac3b314354e8ce5175f135bcc64f.tar.xz zen-24e43a913f29ac3b314354e8ce5175f135bcc64f.zip | |
switch to xmake for package management (#611)
This change removes our dependency on vcpkg for package management, in favour of bringing some code in-tree in the `thirdparty` folder as well as using the xmake build-in package management feature. For the latter, all the package definitions are maintained in the zen repo itself, in the `repo` folder.
It should now also be easier to build the project as it will no longer depend on having the right version of vcpkg installed, which has been a common problem for new people coming in to the codebase. Now you should only need xmake to build.
* Bumps xmake requirement on github runners to 2.9.9 to resolve an issue where xmake on Windows invokes cmake with `v144` toolchain which does not exist
* BLAKE3 is now in-tree at `thirdparty/blake3`
* cpr is now in-tree at `thirdparty/cpr`
* cxxopts is now in-tree at `thirdparty/cxxopts`
* fmt is now in-tree at `thirdparty/fmt`
* robin-map is now in-tree at `thirdparty/robin-map`
* ryml is now in-tree at `thirdparty/ryml`
* sol2 is now in-tree at `thirdparty/sol2`
* spdlog is now in-tree at `thirdparty/spdlog`
* utfcpp is now in-tree at `thirdparty/utfcpp`
* xmake package repo definitions is in `repo`
* implemented support for sanitizers. ASAN is supported on windows, TSAN, UBSAN, MSAN etc are supported on Linux/MacOS though I have not yet tested it extensively on MacOS
* the zencore encryption implementation also now supports using mbedTLS which is used on MacOS, though for now we still use openssl on Linux
* crashpad
* bumps libcurl to 8.11.0 (from 8.8.0) which should address a rare build upload bug
Diffstat (limited to 'thirdparty/ryml/test/test_stack.cpp')
| -rw-r--r-- | thirdparty/ryml/test/test_stack.cpp | 857 |
1 files changed, 857 insertions, 0 deletions
diff --git a/thirdparty/ryml/test/test_stack.cpp b/thirdparty/ryml/test/test_stack.cpp new file mode 100644 index 000000000..73d7b2cea --- /dev/null +++ b/thirdparty/ryml/test/test_stack.cpp @@ -0,0 +1,857 @@ +#ifdef RYML_SINGLE_HEADER +#include "ryml_all.hpp" +#else +#include "c4/yml/detail/stack.hpp" +#endif +#include <gtest/gtest.h> +#include "./callbacks_tester.hpp" + + +//------------------------------------------- + +namespace c4 { +namespace yml { + +namespace detail { + +template<size_t N> +using istack = stack<int, N>; +using ip = int const*; + +template<size_t N> +void to_large(istack<N> *s) +{ + size_t sz = 3u * N; + s->reserve(sz); + EXPECT_NE(s->m_stack, s->m_buf); +} + +template<size_t N> +void fill_to_large(istack<N> *s) +{ + size_t sz = 3u * N; + s->reserve(sz); + for(int i = 0, e = (int)sz; i < e; ++i) + s->push(i); + EXPECT_NE(s->m_stack, s->m_buf); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +template<size_t N> +void test_stack_small_vs_large() +{ + istack<N> s; + for(size_t i = 0; i < N; ++i) + { + s.push(static_cast<int>(i)); + EXPECT_EQ(s.size(), i+1); + } + EXPECT_EQ(s.size(), N); + EXPECT_EQ(s.m_stack, s.m_buf); + for(size_t i = 0; i < N; ++i) + { + EXPECT_EQ(s.top(N-1-i), static_cast<int>(i)); + } + s.push(N); + EXPECT_NE(s.m_stack, s.m_buf); + EXPECT_EQ(s.top(), static_cast<int>(N)); + EXPECT_EQ(s.pop(), static_cast<int>(N)); + EXPECT_NE(s.m_stack, s.m_buf); + for(size_t i = 0; i < N; ++i) + { + EXPECT_EQ(s.top(N-1-i), static_cast<int>(i)); + } +} + +TEST(stack, small_vs_large) +{ + test_stack_small_vs_large<8>(); + test_stack_small_vs_large<16>(); + test_stack_small_vs_large<32>(); + test_stack_small_vs_large<128>(); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +template<size_t N> +void test_copy_ctor() +{ + istack<N> src; + + // small + for(size_t i = 0; i < N; ++i) + { + src.push((int)i); + } + EXPECT_EQ(src.m_stack, src.m_buf); + ip b = src.begin(); + { + istack<N> dst(src); + EXPECT_EQ(dst.size(), src.size()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ((ip)src.begin(), b); + EXPECT_NE((ip)dst.begin(), (ip)src.begin()); + } + + // large + for(size_t i = 0; i < 2*N; ++i) + { + src.push((int)i); // large + } + EXPECT_NE(src.m_stack, src.m_buf); + b = src.begin(); + { + istack<N> dst(src); + EXPECT_EQ(dst.size(), src.size()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ((ip)src.begin(), b); + EXPECT_NE((ip)dst.begin(), (ip)src.begin()); + } +} + +TEST(stack, copy_ctor) +{ + test_copy_ctor<4>(); + test_copy_ctor<8>(); + test_copy_ctor<64>(); + test_copy_ctor<128>(); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +template<size_t N> +void test_move_ctor() +{ + istack<N> src; + + // small + for(size_t i = 0; i < N; ++i) + { + src.push((int)i); + } + EXPECT_EQ(src.m_stack, src.m_buf); + ip b = src.begin(); + size_t sz = src.size(); + { + istack<N> dst(std::move(src)); + EXPECT_EQ(dst.size(), sz); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_NE(dst.m_stack, b); + EXPECT_EQ(src.size(), size_t(0)); + EXPECT_EQ((ip)src.begin(), src.m_buf); + EXPECT_NE((ip)dst.begin(), b); + } + EXPECT_EQ(src.size(), size_t(0)); + EXPECT_EQ(src.capacity(), N); + EXPECT_EQ(src.m_stack, src.m_buf); + + // redo + for(size_t i = 0; i < N; ++i) + { + src.push((int)i); + } + EXPECT_EQ(src.size(), N); + EXPECT_EQ(src.capacity(), N); + EXPECT_EQ(src.m_stack, src.m_buf); + // large + for(size_t i = 0; i < 2*N; ++i) + { + src.push((int)i); // large + } + EXPECT_EQ(src.size(), 3*N); + EXPECT_NE(src.m_stack, src.m_buf); + b = src.begin(); + sz = src.size(); + { + istack<N> dst(std::move(src)); + EXPECT_EQ(dst.size(), sz); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(dst.m_stack, b); + EXPECT_EQ(src.capacity(), N); + EXPECT_EQ(src.size(), size_t(0)); + EXPECT_EQ((ip)src.begin(), src.m_buf); + EXPECT_EQ((ip)dst.begin(), b); + } +} + +TEST(stack, move_ctor) +{ + test_move_ctor<4>(); + test_move_ctor<8>(); + test_move_ctor<64>(); + test_move_ctor<128>(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +template<size_t N> +void test_copy_assign() +{ + istack<N> dst; + istack<N> srcs; // small + istack<N> srcl; // large + + for(size_t i = 0; i < N; ++i) + { + srcs.push((int)i); // small + srcl.push((int)i); // large + } + for(size_t i = 0; i < 2*N; ++i) + { + srcl.push((int)i); // large + } + EXPECT_EQ(srcs.m_stack, srcs.m_buf); + EXPECT_NE(srcl.m_stack, srcl.m_buf); + + ip bs = srcs.begin(), bl = srcl.begin(); + + { + dst = srcs; + EXPECT_EQ(dst.size(), srcs.size()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ((ip)srcs.begin(), bs); + EXPECT_NE((ip)dst.begin(), (ip)srcs.begin()); + } + + { + dst = srcl; + EXPECT_EQ(dst.size(), srcl.size()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ((ip)srcl.begin(), bl); + EXPECT_NE((ip)dst.begin(), (ip)srcl.begin()); + } + + { + dst = srcs; + EXPECT_EQ(dst.size(), srcs.size()); + EXPECT_NE(dst.m_stack, dst.m_buf); // it stays in long mode (it's not trimmed when assigned from a short-mode stack) + EXPECT_EQ((ip)srcs.begin(), bs); + EXPECT_NE((ip)dst.begin(), (ip)srcs.begin()); + } +} + +TEST(stack, copy_assign) +{ + test_copy_assign<4>(); + test_copy_assign<8>(); + test_copy_assign<64>(); + test_copy_assign<128>(); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +template<size_t N> +void test_move_assign() +{ + istack<N> srcs, srcl, dst; + + for(size_t i = 0; i < N; ++i) + { + srcs.push((int)i); // small + srcl.push((int)i); // large + } + for(size_t i = 0; i < 2*N; ++i) + { + srcl.push((int)i); // large + } + EXPECT_EQ(srcs.m_stack, srcs.m_buf); + EXPECT_NE(srcl.m_stack, srcl.m_buf); + + ip bs = srcs.begin()/*, bl = srcl.begin()*/; + size_t szs = srcs.size(), szl = srcl.size(); + + for(int i = 0; i < 10; ++i) + { + EXPECT_FALSE(srcs.empty()); + EXPECT_TRUE(dst.empty()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(srcs.m_stack, srcs.m_buf); + + dst = std::move(srcs); + EXPECT_TRUE(srcs.empty()); + EXPECT_FALSE(dst.empty()); + EXPECT_EQ(srcs.size(), size_t(0)); + EXPECT_EQ(srcs.capacity(), N); + EXPECT_EQ(dst.size(), szs); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(srcs.m_stack, srcs.m_buf); + EXPECT_EQ((ip)srcs.begin(), bs); + EXPECT_NE((ip)dst.begin(), (ip)srcs.begin()); + + srcs = std::move(dst); + } + + for(int i = 0; i < 10; ++i) + { + EXPECT_EQ(srcl.size(), 3*N); + EXPECT_FALSE(srcl.empty()); + EXPECT_TRUE(dst.empty()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_NE(srcl.m_stack, srcl.m_buf); + + dst = std::move(srcl); + EXPECT_TRUE(srcl.empty()); + EXPECT_FALSE(dst.empty()); + EXPECT_EQ(srcl.size(), size_t(0)); + EXPECT_EQ(srcl.capacity(), N); + EXPECT_EQ(dst.size(), szl); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(srcl.m_stack, srcl.m_buf); + EXPECT_EQ((ip)srcl.begin(), srcl.m_buf); + EXPECT_NE((ip)dst.begin(), (ip)srcl.begin()); + + srcl = std::move(dst); + } +} + +TEST(stack, move_assign) +{ + test_move_assign<4>(); + test_move_assign<8>(); + test_move_assign<64>(); + test_move_assign<128>(); +} + + +//----------------------------------------------------------------------------- + +template<size_t N> +void test_callbacks_default_ctor() +{ + CallbacksTester td; + CallbacksTester ts; + istack<N> dst; + EXPECT_EQ(dst.m_callbacks, get_callbacks()); +} + +TEST(stack, callbacks_default_ctor) +{ + test_callbacks_default_ctor<4>(); + test_callbacks_default_ctor<8>(); + test_callbacks_default_ctor<64>(); + test_callbacks_default_ctor<128>(); +} + +template<size_t N> +void test_callbacks_ctor() +{ + CallbacksTester td; + CallbacksTester ts; + istack<N> dst(td.callbacks()); + ASSERT_EQ(dst.m_callbacks, td.callbacks()); +} + +TEST(stack, callbacks_ctor) +{ + test_callbacks_ctor<4>(); + test_callbacks_ctor<8>(); + test_callbacks_ctor<64>(); + test_callbacks_ctor<128>(); +} + + +//----------------------------------------------------------------------------- +// copy ctor + +template<size_t N> +void test_callbacks_copy_ctor_small() +{ + CallbacksTester ts("src"); + CallbacksTester td("dst"); + { + istack<N> src(ts.callbacks()); + EXPECT_EQ(src.size(), 0u); + EXPECT_EQ(src.capacity(), N); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + size_t nbefore = ts.num_allocs; + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + istack<N> dst(src); + EXPECT_EQ(dst.size(), 0u); + EXPECT_EQ(dst.capacity(), N); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, nbefore); + EXPECT_EQ(td.num_allocs, 0u); + } +} + +template<size_t N> +void test_callbacks_copy_ctor_large_unfilled() +{ + CallbacksTester ts("src"); + CallbacksTester td("dst"); + { + istack<N> src(ts.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + to_large(&src); + ASSERT_GT(src.capacity(), N); + size_t nbefore = ts.num_allocs; + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(ts.num_allocs, 0u); + istack<N> dst(src); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + ASSERT_NE(dst.m_callbacks, td.callbacks()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, nbefore); + EXPECT_EQ(td.num_allocs, 0u); + } +} + +template<size_t N> +void test_callbacks_copy_ctor_large_filled() +{ + CallbacksTester ts("src"); + CallbacksTester td("dst"); + { + istack<N> src(ts.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + fill_to_large(&src); + ASSERT_GT(src.capacity(), N); + size_t nbefore = ts.num_allocs; + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(ts.num_allocs, 0u); + istack<N> dst(src); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + ASSERT_NE(dst.m_callbacks, td.callbacks()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_GT(ts.num_allocs, nbefore); + EXPECT_EQ(td.num_allocs, 0u); + } +} + +TEST(stack, callbacks_copy_ctor_small) +{ + test_callbacks_copy_ctor_small<4>(); + test_callbacks_copy_ctor_small<8>(); + test_callbacks_copy_ctor_small<64>(); + test_callbacks_copy_ctor_small<128>(); +} + +TEST(stack, callbacks_copy_ctor_large_unfilled) +{ + test_callbacks_copy_ctor_large_unfilled<4>(); + test_callbacks_copy_ctor_large_unfilled<8>(); + test_callbacks_copy_ctor_large_unfilled<64>(); + test_callbacks_copy_ctor_large_unfilled<128>(); +} + +TEST(stack, callbacks_copy_ctor_large_filled) +{ + test_callbacks_copy_ctor_large_filled<4>(); + test_callbacks_copy_ctor_large_filled<8>(); + test_callbacks_copy_ctor_large_filled<64>(); + test_callbacks_copy_ctor_large_filled<128>(); +} + + +//----------------------------------------------------------------------------- +// copy ctor + +template<size_t N> +void test_callbacks_move_ctor_small() +{ + CallbacksTester ts; + istack<N> src(ts.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + size_t nbefore = ts.num_allocs; + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + istack<N> dst(std::move(src)); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, nbefore); +} + +template<size_t N> +void test_callbacks_move_ctor_large_unfilled() +{ + CallbacksTester ts; + istack<N> src(ts.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + to_large(&src); + size_t nbefore = ts.num_allocs; + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(ts.num_allocs, 0u); + istack<N> dst(std::move(src)); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, nbefore); +} + +template<size_t N> +void test_callbacks_move_ctor_large_filled() +{ + CallbacksTester ts; + istack<N> src(ts.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + fill_to_large(&src); + size_t nbefore = ts.num_allocs; + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(ts.num_allocs, 0u); + istack<N> dst(std::move(src)); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, nbefore); +} + +TEST(stack, callbacks_move_ctor_small) +{ + test_callbacks_move_ctor_small<4>(); + test_callbacks_move_ctor_small<8>(); + test_callbacks_move_ctor_small<64>(); + test_callbacks_move_ctor_small<128>(); +} + +TEST(stack, callbacks_move_ctor_large_unfilled) +{ + test_callbacks_move_ctor_large_unfilled<4>(); + test_callbacks_move_ctor_large_unfilled<8>(); + test_callbacks_move_ctor_large_unfilled<64>(); + test_callbacks_move_ctor_large_unfilled<128>(); +} + +TEST(stack, callbacks_move_ctor_large_filled) +{ + test_callbacks_move_ctor_large_filled<4>(); + test_callbacks_move_ctor_large_filled<8>(); + test_callbacks_move_ctor_large_filled<64>(); + test_callbacks_move_ctor_large_filled<128>(); +} + + +//----------------------------------------------------------------------------- +// copy assign + +template<size_t N> +void test_callbacks_copy_assign_to_empty() +{ + CallbacksTester ts("src"); + CallbacksTester td("dst"); + istack<N> src(ts.callbacks()); + istack<N> dst(td.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + fill_to_large(&src); + size_t nbefore = ts.num_allocs; + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(ts.num_allocs, 0u); + dst = src; + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); + ASSERT_NE(dst.m_callbacks, td.callbacks()); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_GT(ts.num_allocs, nbefore); + EXPECT_EQ(td.num_allocs, 0u); +} + +TEST(stack, callbacks_copy_assign_to_empty) +{ + test_callbacks_copy_assign_to_empty<4>(); + test_callbacks_copy_assign_to_empty<8>(); + test_callbacks_copy_assign_to_empty<64>(); + test_callbacks_copy_assign_to_empty<128>(); +} + +template<size_t N> +void test_callbacks_copy_assign_to_nonempty() +{ + CallbacksTester ts("src"); + { + CallbacksTester td("dst"); + istack<N> src(ts.callbacks()); + istack<N> dst(td.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, td.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + EXPECT_EQ(td.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + fill_to_large(&src); + fill_to_large(&dst); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(td.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + dst = src; + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); // changed to ts + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 2u); + EXPECT_EQ(td.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 1u); + td.check(); + } + ts.check(); +} + +TEST(stack, callbacks_copy_assign_to_nonempty) +{ + test_callbacks_copy_assign_to_nonempty<4>(); + test_callbacks_copy_assign_to_nonempty<8>(); + test_callbacks_copy_assign_to_nonempty<64>(); + test_callbacks_copy_assign_to_nonempty<128>(); +} + +template<size_t N> +void test_callbacks_move_assign_to_empty() +{ + CallbacksTester ts("src"); + { + CallbacksTester td("dst"); + istack<N> src(ts.callbacks()); + istack<N> dst(td.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, td.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + EXPECT_EQ(td.num_allocs, 0u); + fill_to_large(&src); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_EQ(dst.m_stack, dst.m_buf); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(td.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + dst = std::move(src); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); // changed to ts + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(td.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + td.check(); + } + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 1u); + ts.check(); +} + +TEST(stack, callbacks_move_assign_to_empty) +{ + test_callbacks_move_assign_to_empty<4>(); + test_callbacks_move_assign_to_empty<8>(); + test_callbacks_move_assign_to_empty<64>(); + test_callbacks_move_assign_to_empty<128>(); +} + +template<size_t N> +void test_callbacks_move_assign_to_nonempty() +{ + CallbacksTester ts("src"); + { + CallbacksTester td("dst"); + istack<N> src(ts.callbacks()); + istack<N> dst(td.callbacks()); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, td.callbacks()); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 0u); + EXPECT_EQ(td.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + fill_to_large(&src); + fill_to_large(&dst); + EXPECT_NE(src.m_stack, src.m_buf); + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(td.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 0u); + dst = std::move(src); + ASSERT_EQ(src.m_callbacks, ts.callbacks()); + ASSERT_EQ(dst.m_callbacks, ts.callbacks()); // changed to ts + EXPECT_NE(dst.m_stack, dst.m_buf); + EXPECT_EQ(src.m_stack, src.m_buf); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(td.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(td.num_deallocs, 1u); + td.check(); + } + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 1u); + ts.check(); +} + +TEST(stack, callbacks_move_assign_to_nonempty) +{ + test_callbacks_move_assign_to_nonempty<4>(); + test_callbacks_move_assign_to_nonempty<8>(); + test_callbacks_move_assign_to_nonempty<64>(); + test_callbacks_move_assign_to_nonempty<128>(); +} + + +//----------------------------------------------------------------------------- + +template<size_t N> +void test_reserve() +{ + { + CallbacksTester ts; + { + istack<N> s(ts.callbacks()); + EXPECT_EQ(ts.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(s.capacity(), N); + s.reserve(4*N); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(s.capacity(), 4*N); + } + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 1u); + ts.check(); + } + { + CallbacksTester ts; + { + istack<N> s(ts.callbacks()); + EXPECT_EQ(ts.num_allocs, 0u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(s.capacity(), N); + s.reserve(4*N); + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 0u); + EXPECT_EQ(s.capacity(), 4*N); + s._free(); + } + EXPECT_EQ(ts.num_allocs, 1u); + EXPECT_EQ(ts.num_deallocs, 1u); + ts.check(); + } +} + +TEST(stack, reserve_capacity) +{ + test_reserve<10>(); + test_reserve<20>(); +} + + +template<size_t N, int NumTimes> +void grow_to_large__push() +{ + istack<N> s; + int ni = (int)N; + for(int i = 0; i < NumTimes * ni; ++i) + { + s.push(i); + if(i < ni) + EXPECT_EQ(s.m_stack, s.m_buf) << i; + else + EXPECT_NE(s.m_stack, s.m_buf) << i; + } + for(int i = 0; i < NumTimes * ni; ++i) + { + EXPECT_EQ(s.bottom((size_t)i), i); + } +} + +TEST(stack, push_to_large_twice) +{ + grow_to_large__push<10, 8>(); + grow_to_large__push<20, 8>(); + grow_to_large__push<32, 8>(); +} + +template<size_t N, int NumTimes> +void grow_to_large__push_top() +{ + istack<N> s; + int ni = (int)N; + s.push(0); + for(int i = 1; i < NumTimes * ni; ++i) + { + s.push_top(); + EXPECT_EQ(s.top(), i-1) << i; + s.top() = i; + if(i < ni) + EXPECT_EQ(s.m_stack, s.m_buf) << i; + else + EXPECT_NE(s.m_stack, s.m_buf) << i; + } + for(int i = 0; i < NumTimes * ni; ++i) + { + EXPECT_EQ(s.bottom((size_t)i), i); + } +} + +TEST(stack, push_top_to_large_twice) +{ + grow_to_large__push_top<10, 8>(); + grow_to_large__push_top<20, 8>(); + grow_to_large__push_top<32, 8>(); +} + +} // namespace detail +} // namespace yml +} // namespace c4 + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +// this is needed to use the test case library + +#ifndef RYML_SINGLE_HEADER +#include "c4/substr.hpp" +#endif + +namespace c4 { +namespace yml { +struct Case; +Case const* get_case(csubstr /*name*/) +{ + return nullptr; +} + +} // namespace yml +} // namespace c4 |