mirror of
https://github.com/AdaCore/cvc5.git
synced 2026-02-12 12:32:16 -08:00
Before, we were storing elements in a CDList by allocating raw buffers. When reallocating space, we were moving the elements using memcpy without invoking the copy or move constructors, which lead to warnings with GCC 8.1 (and could be problematic, depending on the elements stored in the list). This commit changes the underlying storage to use std::vector. This implies a couple of changes: The destructor of the elements in CDList is now always called, the elements must be CopyAssignable (which does not work with classes that have const data members), and some specialization is needed for CDList<bool> because std::vector<bool> is (possibly) specialized in the STL to be a vector of bits and doesn't support taking the address of an element. After this change, the constructor of CDList now takes a `callCleanup` parameter instead of the `callDestructor` to determine whether the cleanup function should be called or not when truncating the list (we can consider removing this parameter altogether in the future since the default cleanup function is a noop). I've checked the usages of CDList/CDQueue (which is based on CDList), and this should have no effect.
193 lines
4.6 KiB
C++
193 lines
4.6 KiB
C++
/******************************************************************************
|
|
* Top contributors (to current version):
|
|
* Aina Niemetz, Andres Noetzli, Morgan Deters
|
|
*
|
|
* This file is part of the cvc5 project.
|
|
*
|
|
* Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
|
|
* in the top-level source directory and their institutional affiliations.
|
|
* All rights reserved. See the file COPYING in the top-level source
|
|
* directory for licensing information.
|
|
* ****************************************************************************
|
|
*
|
|
* Black box testing of cvc5::context::CDList<>.
|
|
*/
|
|
|
|
#include <limits.h>
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "base/exception.h"
|
|
#include "context/cdlist.h"
|
|
#include "test_context.h"
|
|
|
|
namespace cvc5::internal {
|
|
|
|
using namespace context;
|
|
|
|
namespace test {
|
|
|
|
class TestObject
|
|
{
|
|
public:
|
|
// Test support for elements without default constructor
|
|
TestObject() = delete;
|
|
|
|
TestObject(bool* cleanupCalled) : d_cleanupCalled(cleanupCalled) {}
|
|
|
|
bool* d_cleanupCalled;
|
|
};
|
|
|
|
class TestCleanup
|
|
{
|
|
public:
|
|
TestCleanup() {}
|
|
void operator()(TestObject& o) { (*o.d_cleanupCalled) = true; }
|
|
};
|
|
|
|
class TestContextBlackCDList : public TestContext
|
|
{
|
|
protected:
|
|
void list_test(int n)
|
|
{
|
|
list_test(n, true);
|
|
list_test(n, false);
|
|
}
|
|
|
|
void list_test(int32_t n, bool callDestructor)
|
|
{
|
|
CDList<int32_t> list(d_context.get(), callDestructor);
|
|
|
|
ASSERT_TRUE(list.empty());
|
|
for (int32_t i = 0; i < n; ++i)
|
|
{
|
|
ASSERT_EQ(list.size(), (uint32_t)i);
|
|
list.push_back(i);
|
|
ASSERT_FALSE(list.empty());
|
|
ASSERT_EQ(list.back(), i);
|
|
int32_t i2 = 0;
|
|
for (CDList<int32_t>::const_iterator j = list.begin(); j != list.end();
|
|
++j)
|
|
{
|
|
ASSERT_EQ(*j, i2++);
|
|
}
|
|
}
|
|
ASSERT_EQ(list.size(), (uint32_t)n);
|
|
|
|
for (int32_t i = 0; i < n; ++i)
|
|
{
|
|
ASSERT_EQ(list[i], i);
|
|
}
|
|
}
|
|
};
|
|
|
|
TEST_F(TestContextBlackCDList, CDList10) { list_test(10); }
|
|
|
|
TEST_F(TestContextBlackCDList, CDList15) { list_test(15); }
|
|
|
|
TEST_F(TestContextBlackCDList, CDList20) { list_test(20); }
|
|
|
|
TEST_F(TestContextBlackCDList, CDList35) { list_test(35); }
|
|
|
|
TEST_F(TestContextBlackCDList, CDList50) { list_test(50); }
|
|
|
|
TEST_F(TestContextBlackCDList, CDList99) { list_test(99); }
|
|
|
|
TEST_F(TestContextBlackCDList, destructor_called)
|
|
{
|
|
bool shouldRemainFalse = false;
|
|
bool shouldFlipToTrue = false;
|
|
bool alsoFlipToTrue = false;
|
|
bool shouldAlsoRemainFalse = false;
|
|
bool aThirdFalse = false;
|
|
|
|
CDList<TestObject, TestCleanup> listT(d_context.get(), true, TestCleanup());
|
|
CDList<TestObject, TestCleanup> listF(d_context.get(), false, TestCleanup());
|
|
|
|
TestObject shouldRemainFalseDSO(&shouldRemainFalse);
|
|
TestObject shouldFlipToTrueDSO(&shouldFlipToTrue);
|
|
TestObject alsoFlipToTrueDSO(&alsoFlipToTrue);
|
|
TestObject shouldAlsoRemainFalseDSO(&shouldAlsoRemainFalse);
|
|
TestObject aThirdFalseDSO(&aThirdFalse);
|
|
|
|
listT.push_back(shouldAlsoRemainFalseDSO);
|
|
listF.push_back(shouldAlsoRemainFalseDSO);
|
|
|
|
d_context->push();
|
|
|
|
listT.push_back(shouldFlipToTrueDSO);
|
|
listT.push_back(alsoFlipToTrueDSO);
|
|
|
|
listF.push_back(shouldRemainFalseDSO);
|
|
listF.push_back(shouldAlsoRemainFalseDSO);
|
|
listF.push_back(aThirdFalseDSO);
|
|
|
|
ASSERT_EQ(shouldRemainFalse, false);
|
|
ASSERT_EQ(shouldFlipToTrue, false);
|
|
ASSERT_EQ(alsoFlipToTrue, false);
|
|
ASSERT_EQ(shouldAlsoRemainFalse, false);
|
|
ASSERT_EQ(aThirdFalse, false);
|
|
|
|
d_context->pop();
|
|
|
|
ASSERT_EQ(shouldRemainFalse, false);
|
|
ASSERT_EQ(shouldFlipToTrue, true);
|
|
ASSERT_EQ(alsoFlipToTrue, true);
|
|
ASSERT_EQ(shouldAlsoRemainFalse, false);
|
|
ASSERT_EQ(aThirdFalse, false);
|
|
}
|
|
|
|
TEST_F(TestContextBlackCDList, empty_iterator)
|
|
{
|
|
CDList<int>* list = new (true) CDList<int>(d_context.get());
|
|
ASSERT_EQ(list->begin(), list->end());
|
|
list->deleteSelf();
|
|
}
|
|
|
|
TEST_F(TestContextBlackCDList, pop_below_level_created)
|
|
{
|
|
d_context->push();
|
|
CDList<int32_t> list(d_context.get());
|
|
d_context->popto(0);
|
|
list.push_back(42);
|
|
}
|
|
|
|
TEST_F(TestContextBlackCDList, emplace_back)
|
|
{
|
|
int32_t n = 10;
|
|
int32_t start = 42;
|
|
CDList<std::unique_ptr<int32_t>> list(d_context.get());
|
|
|
|
for (int32_t i = 0; i < n; i++)
|
|
{
|
|
list.emplace_back(new int32_t(start + i));
|
|
}
|
|
for (int32_t i = 0; i < n; i++)
|
|
{
|
|
ASSERT_EQ(*list[i], start + i);
|
|
}
|
|
ASSERT_EQ(list.size(), n);
|
|
|
|
d_context->push();
|
|
for (int32_t i = 0; i < n; i++)
|
|
{
|
|
list.emplace_back(new int32_t(start + n + i));
|
|
}
|
|
for (int32_t i = 0; i < n * 2; i++)
|
|
{
|
|
ASSERT_EQ(*list[i], start + i);
|
|
}
|
|
ASSERT_EQ(list.size(), n * 2);
|
|
d_context->pop();
|
|
|
|
for (int32_t i = 0; i < n; i++)
|
|
{
|
|
ASSERT_EQ(*list[i], start + i);
|
|
}
|
|
ASSERT_EQ(list.size(), n);
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace cvc5::internal
|