Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #91 progress. #194

Merged
merged 36 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
31c5110
resetting cpp baseline to be the c templates
thirtytwobits Jan 30, 2021
7571c2e
test_support_headers generates without error
thirtytwobits Jan 31, 2021
3e193c8
various progress
thirtytwobits Feb 7, 2021
1f1c645
refocusing on POD first
thirtytwobits Feb 7, 2021
6d3ab90
adding python 3.9 testing
thirtytwobits Feb 10, 2021
c424dcf
progress on c++ POD generation
thirtytwobits Feb 10, 2021
d57a395
bunch of whitespace fixes
thirtytwobits Feb 16, 2021
9b2e764
fixing c build
thirtytwobits Feb 22, 2021
16ff4c7
fixing builds and adding platoform info to generated headers
thirtytwobits Feb 22, 2021
5e9431c
starting a variable-length array type
thirtytwobits Feb 27, 2021
714b0cd
Adding 01heap and updating other submodules
thirtytwobits Feb 28, 2021
993986b
adding bracket operator
thirtytwobits Feb 28, 2021
34f20d6
good progress on the variable length array type
thirtytwobits Feb 28, 2021
3ccd5ca
A lot of stuff in this one:
thirtytwobits Mar 12, 2021
32a75f5
fixing up noexcept specifiers
thirtytwobits Mar 13, 2021
8e93b8b
adding array type override
thirtytwobits Mar 14, 2021
5a9b016
version bump
thirtytwobits Mar 14, 2021
70ac699
fixing git submodules (I think)
thirtytwobits Mar 15, 2021
36b248c
fixing python tests
thirtytwobits Mar 17, 2021
79ab99c
fixing a build problem with unity
thirtytwobits Mar 17, 2021
5189e4b
fixing accidental typo
thirtytwobits Mar 17, 2021
1ee1d84
fixing typing error
thirtytwobits Mar 17, 2021
c73d4d0
progress on fixing up build
thirtytwobits Mar 17, 2021
5cdce00
fixing script permissions
thirtytwobits Mar 17, 2021
b2f0039
disabling coverage for now
thirtytwobits Mar 18, 2021
31edfe4
Fixing GCC 9 and earlier syntax
thirtytwobits Mar 21, 2021
803445f
parallelizing python builds
thirtytwobits Mar 22, 2021
ff3c0b4
fixing script permissions
thirtytwobits Mar 22, 2021
9d24d43
increasing host parallelism
thirtytwobits Mar 23, 2021
808f36c
fixing concurrency issues with native build
thirtytwobits Mar 23, 2021
fd96a1b
fixing my verify overrides.
thirtytwobits Mar 24, 2021
bc478f5
more responses based on the PR
thirtytwobits May 11, 2021
f91de11
More fixups per Pavels comments
thirtytwobits May 31, 2021
f3ae63f
last bits o fixup
thirtytwobits Jun 6, 2021
3309f9b
removing unneeded macro
thirtytwobits Jun 7, 2021
da79d79
disallowing array for var array
thirtytwobits Jun 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
adding bracket operator
  • Loading branch information
thirtytwobits committed May 7, 2021
commit 993986b8d7edb0c16a443aee21fe43072a280e1a
53 changes: 33 additions & 20 deletions src/nunavut/lang/cpp/support/VariableLengthArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class VariableLengthArray
return data_;
}

constexpr const T& operator[](std::size_t i) const
{
return data_[i];
}

constexpr T& operator[](std::size_t i)
{
return data_[i];
}

// +----------------------------------------------------------------------+
// | CAPACITY
// +----------------------------------------------------------------------+
Expand Down Expand Up @@ -72,31 +82,34 @@ class VariableLengthArray
const std::size_t no_shrink_capacity = (clamped_capacity > old_data_size) ? clamped_capacity : old_data_size;
T* new_data = alloc_.allocate(no_shrink_capacity);

if (old_data_size < 0 && new_data != old_data)
if (new_data != nullptr)
{
// The allocator returned new memory. Copy any initialized objects in the old region to the new one.
// Check for memory overlap.
const std::size_t old_data_size_bytes = (old_data_size * sizeof(T));
if (
(old_data + old_data_size_bytes < new_data)
||
(new_data + old_data_size_bytes < old_data)
)
if (old_data_size > 0 && new_data != old_data)
{
// Initialized regions do not overlap. Use memcpy.
std::memcpy(new_data, old_data, old_data_size_bytes);
// The allocator returned new memory. Copy any initialized objects in the old region to the new one.
// Check for memory overlap.
const std::size_t old_data_size_bytes = (old_data_size * sizeof(T));
if (
(old_data + old_data_size_bytes < new_data)
||
(new_data + old_data_size_bytes < old_data)
)
{
// Initialized regions do not overlap. Use memcpy.
std::memcpy(new_data, old_data, old_data_size_bytes);
}
else
{
// Initialized regions overlap. Use memmove.
std::memmove(new_data, old_data, old_data_size_bytes);
}
}
else
{
// Initialized regions overlap. Use memmove.
std::memmove(new_data, old_data, old_data_size_bytes);
}
}

data_ = new_data;
capacity_ = no_shrink_capacity;
data_ = new_data;
capacity_ = no_shrink_capacity;
}

return no_shrink_capacity;
return capacity_;
}


Expand Down
97 changes: 90 additions & 7 deletions verification/cpp/suite/test_var_len_arr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <type_traits>
#include "o1heap/o1heap.h"

/**
* Pavel's O(1) Heap Allocator wrapped in an std::allocator concept.
*/
template<typename T, std::size_t SizeCount>
class O1HeapAllocator
{
Expand All @@ -24,25 +27,62 @@ class O1HeapAllocator

T* allocate( std::size_t n )
{
return reinterpret_cast<T*>(o1heapAllocate(heap_alloc_, n));
return reinterpret_cast<T*>(o1heapAllocate(heap_alloc_, n * sizeof(T)));
}

private:
typename std::aligned_storage<sizeof(T), O1HEAP_ALIGNMENT>::type heap_[SizeCount];
O1HeapInstance* heap_alloc_;
};

/**
* A Junky static allocator.
*/
template<typename T, std::size_t SizeCount>
class JunkyStaticAllocator
{
public:
using value_type = T;

JunkyStaticAllocator()
: data_()
{
}

T* allocate( std::size_t n )
{
if (n < SizeCount)
{
return reinterpret_cast<T*>(&data_[0]);
}
else
{
return nullptr;
}
}

private:
typename std::aligned_storage<sizeof(T), alignof(T)>::type data_[SizeCount];
};

// +----------------------------------------------------------------------+
/**
* Test suite for running multiple allocators against the variable length array type.
*/
template <typename T>
class VariableLengthArrayTestSuite : public ::testing::Test
class VLATestsGeneric : public ::testing::Test
{
};

using VariableLengthArrayTestAllocators = ::testing::Types<std::allocator<int>,
using VLATestsGenericAllocators = ::testing::Types<std::allocator<int>,
std::allocator<long long>,
O1HeapAllocator<int, O1HEAP_ALIGNMENT * 8>>;
TYPED_TEST_SUITE(VariableLengthArrayTestSuite, VariableLengthArrayTestAllocators,);
O1HeapAllocator<int, O1HEAP_ALIGNMENT * 8>,
JunkyStaticAllocator<int, 10>>;
TYPED_TEST_SUITE(VLATestsGeneric, VLATestsGenericAllocators,);


TYPED_TEST(VariableLengthArrayTestSuite, TestReserve)

TYPED_TEST(VLATestsGeneric, TestReserve)
{
nunavut::support::VariableLengthArray<typename TypeParam::value_type, TypeParam, 10> subject;
ASSERT_EQ(nullptr, subject.data());
Expand All @@ -51,7 +91,7 @@ TYPED_TEST(VariableLengthArrayTestSuite, TestReserve)
ASSERT_EQ(10U, subject.max_size());
ASSERT_EQ(nullptr, subject.push_back_no_alloc(1));

subject.reserve(1);
ASSERT_EQ(1U, subject.reserve(1));

ASSERT_EQ(1U, subject.capacity());
ASSERT_EQ(0U, subject.size());
Expand All @@ -60,3 +100,46 @@ TYPED_TEST(VariableLengthArrayTestSuite, TestReserve)
ASSERT_EQ(*pushed, 1);
ASSERT_EQ(1U, subject.size());
}


// +----------------------------------------------------------------------+
/**
* Test suite for running static allocators against the variable length array type.
*/
template <typename T>
class VLATestsStatic : public ::testing::Test
{
};

using VLATestsStaticAllocators = ::testing::Types<O1HeapAllocator<int, O1HEAP_ALIGNMENT * 8>,
JunkyStaticAllocator<int, 10>>;
TYPED_TEST_SUITE(VLATestsStatic, VLATestsStaticAllocators,);

TYPED_TEST(VLATestsStatic, TestOutOfMemory)
{
nunavut::support::VariableLengthArray<typename TypeParam::value_type, TypeParam, 10> subject;
ASSERT_EQ(0U, subject.capacity());

std::size_t last_capacity = subject.capacity();
bool did_run_out_of_memory = false;
std::size_t ran_out_of_memory_at = 0;
for(std::size_t i = 1; i <= 1024; ++i)
{
if (last_capacity == subject.reserve(i))
{
did_run_out_of_memory = true;
ran_out_of_memory_at = i - 1;
break;
}
last_capacity = subject.capacity();
typename TypeParam::value_type* pushed = subject.push_back_no_alloc(static_cast<typename TypeParam::value_type>(i));
ASSERT_NE(nullptr, pushed);
ASSERT_EQ(static_cast<typename TypeParam::value_type>(i), *pushed);
}
ASSERT_TRUE(did_run_out_of_memory);
ASSERT_EQ(nullptr,subject.push_back_no_alloc(0));
for(std::size_t i = 0; i < ran_out_of_memory_at; ++i)
{
ASSERT_EQ(static_cast<typename TypeParam::value_type>(i+1), subject[i]);
}
}