Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dwarfovich committed Sep 12, 2024
1 parent 89b6056 commit 9d093b5
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 29 deletions.
104 changes: 75 additions & 29 deletions HW3/cc_lib/include/cc/forward_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@ namespace cc {

namespace details {

template<typename T>
struct Node
{
T data;
Node* nextNode = nullptr;
};

template<typename T>
struct DataNode : Node
{
DataNode() = default;

DataNode(const T& aData, Node* nextNode) : Node { nextNode }, data { aData } {}

T data;
};

} // namespace details

template<class ForwardList>
Expand All @@ -30,20 +38,20 @@ class ForwardListIterator
public: // methods
ForwardListIterator() = default;
ForwardListIterator(const ForwardList* list);
ForwardListIterator(const ForwardList* list, details::Node<value_type>* node);
ForwardListIterator(const ForwardList* list, details::Node* node);

bool operator==(const ForwardListIterator& rhs) const;
auto operator<=>(const ForwardListIterator&) const = default;
const value_type& operator*() const { return *this; }
value_type& operator*() { return node->data; }
bool operator==(const ForwardListIterator& rhs) const;
auto operator<=>(const ForwardListIterator&) const = default;
const value_type& operator*() const { return static_cast<details::DataNode<ForwardList::value_type>*>(node)->data; }
value_type& operator*() { return static_cast<details::DataNode<ForwardList::value_type>*>(node)->data; }
ForwardListIterator& operator++();
ForwardListIterator operator++(int);

details::Node<value_type>* getNode() const noexcept { return node; }
details::Node* getNode() const noexcept { return node; }

private:
details::Node<value_type>* node = nullptr;
const ForwardList* list = nullptr;
details::Node* node = nullptr;
const ForwardList* list = nullptr;
};

template<typename T, typename Allocator = std::allocator<T>>
Expand All @@ -60,24 +68,29 @@ class ForwardList
using const_iterator = ForwardListIterator<const ForwardList<T, Allocator>>;

public: // methods
iterator begin() const;
ForwardList();

allocator_type get_allocator() const noexcept;
iterator before_begin() const;
const_iterator cbefore_begin() const;
iterator begin() const;
const_iterator cbegin() const;
iterator end() const;
iterator end() const;
const_iterator cend() const;
iterator insert_after(iterator position, const value_type& value);
bool empty() const noexcept;
iterator insert_after(iterator position, const value_type& value);
bool empty() const noexcept;
std::size_t size();

private: // data
Allocator allocator;
details::Node<T>* firstNode = nullptr;
std::size_t size = 0;
Allocator allocator;
details::Node head;
std::size_t listSize = 0;
};

template<class ForwardList>
ForwardListIterator<ForwardList>& ForwardListIterator<ForwardList>::operator++()
{
if (node)
node = node->nextNode;
node = node->nextNode;
return *this;
}

Expand All @@ -95,7 +108,7 @@ ForwardListIterator<ForwardList>::ForwardListIterator(const ForwardList* aList)
}

template<class ForwardList>
ForwardListIterator<ForwardList>::ForwardListIterator(const ForwardList* aList, details::Node<value_type>* aNode)
ForwardListIterator<ForwardList>::ForwardListIterator(const ForwardList* aList, details::Node* aNode)
: list { aList }, node { aNode }
{
}
Expand All @@ -106,32 +119,53 @@ bool ForwardListIterator<ForwardList>::operator==(const ForwardListIterator& rhs
return node == rhs.node && list == rhs.list;
}

template<typename T, typename Allocator>
ForwardList<T, Allocator>::ForwardList()
{
}

template<typename T, typename Allocator>
auto ForwardList<T, Allocator>::insert_after(iterator position, const value_type& value) -> iterator
{
auto next = std::next(position);
using AllocatorTraits = std::allocator_traits<Allocator>;

using NodeAllcoator = typename std::allocator_traits<Allocator>::template rebind_alloc<details::Node<T>>;
using NodeAllcoator = typename std::allocator_traits<Allocator>::template rebind_alloc<details::DataNode<T>>;
NodeAllcoator nodeAllocator = allocator;
auto* newNode = nodeAllocator.allocate(1);
using NodeAllocatorTraits = std::allocator_traits<decltype(nodeAllocator)>;
NodeAllocatorTraits::construct(nodeAllocator, newNode, value, next.getNode());

if(!firstNode){
firstNode = newNode;
// NodeAllocatorTraits::construct(nodeAllocator, newNode, value);
if(position == begin()){
NodeAllocatorTraits::construct(nodeAllocator, newNode, value, nullptr);
} else{
auto next = std::next(position);
NodeAllocatorTraits::construct(nodeAllocator, newNode, value, next.getNode());
}

if (empty()) {
head.nextNode = newNode;
} else {
position.getNode()->nextNode = newNode;
}
++size;

return {this, newNode};
}

template<typename T, typename Allocator>
auto ForwardList<T, Allocator>::before_begin() const -> iterator
{
return { this, const_cast<details::Node*>(&head) };
}

template<typename T, typename Allocator>
auto ForwardList<T, Allocator>::cbefore_begin() const -> const_iterator
{
return { this, &head };
}

template<typename T, typename Allocator>
auto ForwardList<T, Allocator>::begin() const -> iterator
{
return { this, firstNode };
return std::next(before_begin());
}

template<typename T, typename Allocator>
Expand All @@ -155,7 +189,19 @@ auto ForwardList<T, Allocator>::cend() const -> const_iterator
template<typename T, typename Allocator>
bool ForwardList<T, Allocator>::empty() const noexcept
{
return size == 0;
return listSize == 0;
}

template<typename T, typename Allocator>
std::size_t ForwardList<T, Allocator>::size()
{
return listSize;
}

template<typename T, typename Allocator>
auto ForwardList<T, Allocator>::get_allocator() const noexcept -> allocator_type
{
return allocator;
}

} // namespace cc
10 changes: 10 additions & 0 deletions HW3/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ int main()
cc::ForwardList<int> list;
auto iter = list.begin();
list.insert_after(iter, 77);

std::forward_list<short> l;
auto it1 = l.cbefore_begin();
auto it2 = l.cbegin();
//++it2;
auto it3 = l.cend();
/*std::cout << std::boolalpha << (l.cbegin() == l.cbefore_begin()) << '\n';
std::cout << sizeof(list) << ' ' << sizeof(l) << '\n';
std::forward_list<int> l2;
std::cout << std::boolalpha << (l.cbegin() == l.cend()) << '\n';*/

return 0;
}
17 changes: 17 additions & 0 deletions HW3/tests/forward_list_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ TEST(ForwardListTest, ConsequtiveInsertion)
iter = list.insert_after(iter, i);
}

iter = list.begin();
for (int i = 0; iter != list.end(); ++i, ++iter) {
EXPECT_EQ(*iter, i);
}
}

TEST(ForwardListTest, Size)
{
const int inserts = 5;

cc::ForwardList<int> list;
auto iter = list.begin();
for (int i = 0; i < inserts; ++i) {
iter = list.insert_after(iter, i);
EXPECT_EQ(list.size(), static_cast<std::size_t>(i + 1));
}

iter = list.begin();
for (int i = 0; iter != list.end(); ++i, ++iter) {
EXPECT_EQ(*iter, i);
Expand Down

0 comments on commit 9d093b5

Please sign in to comment.