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

Lab4 #3

Merged
merged 10 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion lab4/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ else()
endif()

# описываем основную библиотеку, т.е. библиотеку, содержащую все cpp-файлы, кроме main.cpp
add_library(corelib OBJECT )
add_library(corelib OBJECT SourceTests.cpp)

# описываем исполняемый файл основной программы: это main.cpp + основная библиотека
add_executable(${exe_name} Main.cpp)
Expand Down
291 changes: 291 additions & 0 deletions lab4/FlatMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
#pragma once

#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <sstream>
#include <initializer_list>

const int newCells = 4;

template<typename KeyT, typename ValueT>
struct object {
KeyT key;
ValueT value;
};

template <typename KeyT, typename ValueT,
class Compare = std::less<KeyT>,
class Allocator = std::allocator<object<KeyT, ValueT>>>
class FlatMap {
Allocator alloc;
object<KeyT, ValueT>* map;
int capacity;
int count;

using traits = std::allocator_traits<decltype(alloc)>;

static int binSearch(object<KeyT, ValueT> arr[], int low, int high, const KeyT& x, Compare comp = Compare());
static void shift(object<KeyT, ValueT>* place, int border, int index, const std::string& mode);

template <typename KeyTS, typename ValueTS>
friend void swap(FlatMap<KeyTS, ValueTS>& m1, FlatMap<KeyTS, ValueTS>& m2);

public:
FlatMap();
FlatMap(const FlatMap& other_map);
~FlatMap();

FlatMap& operator = (const FlatMap& other_map);
[[nodiscard]] std::size_t size() const;
ValueT& operator [] (const KeyT& key);

bool contains(const KeyT& key);
std::size_t erase(const KeyT& key);
void clear();

FlatMap(FlatMap&& x) noexcept;
FlatMap& operator = (FlatMap&& x) noexcept;

object<KeyT, ValueT>* begin();
object<KeyT, ValueT>* end();
object<KeyT, ValueT>* find(const KeyT& x);

};

template <typename KeyT, typename ValueT, class Compare, class Allocator>
int FlatMap<KeyT, ValueT, Compare, Allocator>::binSearch(object<KeyT, ValueT> arr[], int low, int high, const KeyT& x, Compare comp) {
while (low <= high) {
int mid = low + (high - low) / 2;

if (arr[mid].key == x) {
return mid;
}

if (comp(arr[mid].key, x)) {
low = mid + 1;
}
else {
high = mid - 1;
}
}

return (-1 * low - 1);
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
void FlatMap<KeyT, ValueT, Compare, Allocator>::shift(object<KeyT, ValueT>* place, int border, int index, const std::string& mode) {
if (mode == "r") {
int end = border;

while (end != index) {
place[end] = place[end - 1];
end--;
}
}
else {
int begin = index;

while (begin != border - 1) {
place[begin] = place[begin + 1];
begin++;
}
}
}

template <typename KeyTS, typename ValueTS>
void swap(FlatMap<KeyTS, ValueTS>& m1, FlatMap<KeyTS, ValueTS>& m2) {
using std::swap;

swap(m1.map, m2.map);
swap(m1.capacity, m2.capacity);
swap(m1.count, m2.count);
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap() : capacity{ newCells }, count { 0 } {
//map = new object<KeyT, ValueT>[newCells];
map = traits::allocate(alloc, newCells);
for (int i = 0; i < newCells; ++i) {
traits::construct(alloc, map + i, object<KeyT, ValueT>());
}
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap(const FlatMap& other_map) : capacity{ other_map.capacity }, count{ other_map.count } {
//map = new object<KeyT, ValueT>[other_map.capacity];
map = traits::allocate(alloc, other_map.capacity);
for (int i = 0; i < other_map.capacity; ++i) {
traits::construct(alloc, map + i, object<KeyT, ValueT>());
}

std::copy(other_map.map, other_map.map + other_map.count, map);
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>::~FlatMap() {
//delete[] map;

for (int i = 0; i < capacity; ++i) {
traits::destroy(alloc, map + i);
}

}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>& FlatMap<KeyT, ValueT, Compare, Allocator>::operator=(const FlatMap& other_map) {
if (this == &other_map) {
return *this;
}

FlatMap copy(other_map);
swap(copy, *this);

return *this;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
std::size_t FlatMap<KeyT, ValueT, Compare, Allocator>::size() const {
return count;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
ValueT& FlatMap<KeyT, ValueT, Compare, Allocator>::operator [] (const KeyT& key) {
if (capacity == 0) {
FlatMap copy(*this);

//copy.map = new object<KeyT, ValueT>[newCells];
copy.map = traits::allocate(alloc, newCells);
for (int i = 0; i < newCells; ++i) {
traits::construct(alloc, copy.map + i, object<KeyT, ValueT>());
}

copy.capacity = newCells;

swap(copy, *this);
}

if (count == 0) {
map[0].key = key;
count++;

return map[0].value;
}

if (count == capacity) {
FlatMap copy(*this);

//auto altMap = new object<KeyT, ValueT>[copy.capacity + newCells];
auto altMap = traits::allocate(alloc, copy.capacity + newCells);
for (int i = 0; i < copy.capacity + newCells; ++i) {
traits::construct(alloc, map + i, object<KeyT, ValueT>());
}

std::copy(copy.map, copy.map + copy.count, altMap);

//delete[] copy.map;
for (int i = 0; i < copy.capacity; ++i) {
traits::destroy(alloc, copy.map + i);
}

copy.map = altMap;
copy.capacity += newCells;

swap(copy, *this);
}

int id = binSearch(map, 0, count - 1, key);

if (id < 0) {
id = (id + 1) * -1;

shift(map, count, id, "r");

map[id].key = key;
count++;
}

return map[id].value;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
bool FlatMap<KeyT, ValueT, Compare, Allocator>::contains(const KeyT& key) {
if (count == 0) {
return false;
}

return binSearch(map, 0, count - 1, key) >= 0;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
std::size_t FlatMap<KeyT, ValueT, Compare, Allocator>::erase(const KeyT& key) {
if (count == 0) {
return 0;
}

int id = binSearch(map, 0, count - 1, key);

if (id < 0) {
return 0;
}
else {
shift(map, count, id, "l");

map[count - 1].key = KeyT();
map[count - 1].value = ValueT();
count--;

return 1;
}
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
void FlatMap<KeyT, ValueT, Compare, Allocator>::clear() {
while (count > 0) {
map[count - 1].key = KeyT();
map[count - 1].value = ValueT();

count--;
}
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>::FlatMap(FlatMap&& x) noexcept : map{ x.map }, capacity{ x.capacity }, count{ x.count } {
x.map = nullptr;
x.capacity = 0;
x.count = 0;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
FlatMap<KeyT, ValueT, Compare, Allocator>& FlatMap<KeyT, ValueT, Compare, Allocator>::operator=(FlatMap&& x) noexcept {
if (this == &x) {
return *this;
}

FlatMap copy(std::move(x));
swap(copy, *this);

return *this;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::begin() {
return map;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::end() {
return map + count;
}

template <typename KeyT, typename ValueT, class Compare, class Allocator>
typename ::object<KeyT, ValueT>* FlatMap<KeyT, ValueT, Compare, Allocator>::find(const KeyT& x) {
if (count == 0) {
return map;
}

int id = binSearch(map, 0, count - 1, x);

return id < 0 ? map + count : map + id;
}
68 changes: 68 additions & 0 deletions lab4/Main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "Tuple.h"
#include "TupleAdd.h"
#include "Parser.h"
#include "FlatMap.h"

int main() {
std::cout << std::endl << "_____Task_№1_____" << std::endl;

std::ofstream testFile("test.txt");
std::tuple<int, std::string, double> t = {5, "abcd", 3.14};

std::cout << t << std::endl;
testFile << t << std::endl;

MyTuple<int, std::string> testTuple(12, "qwe");
std::cout << testTuple << std::endl;

std::cout << "_________________" << std::endl;

std::cout << std::endl << "_____Task_№2_____" << std::endl;

//std::ifstream csv_stream("test.csv");
std::ifstream csv_stream("test1.csv");
//std::ifstream csv_stream("test2.csv");
CsvParser<int, std::string> parser(csv_stream, 0);
//CsvParser<int, std::string, double> parser(std::cin, 0);

for (const auto& rs : parser) {
std::cout << rs << std::endl;
}

std::cout << "_________________" << std::endl;

std::cout << std::endl << "_____Task_№3_____" << std::endl;

FlatMap<std::string, std::string> map1;
FlatMap<std::string, double> map2;
FlatMap<int, std::string> map3;

map1["First_name"] = "Ivan";
map1["Last_name"] = "Ivanov";

for (auto & it : map1) {
std::cout << it.key << ": " << it.value << std::endl;
}

std::cout << "_________________" << std::endl;

map2["pi"] = 3.14;
map2["e"] = 2.71;

for (auto & it : map2) {
std::cout << it.key << ": " << it.value << std::endl;
}
std::cout << "_________________" << std::endl;

map3[1] = "one";
map3[10] = "ten";
map3[5] = "five";

for (auto & it : map3) {
std::cout << it.key << ": " << it.value << std::endl;
}

std::cout << "_________________" << std::endl;

return 0;
}
Loading