Compare commits
No commits in common. "e1d1138653907c9ce33394b97f9a310ba9da81e8" and "5626d1eacb04ca9367de5322161fbac3db9a1059" have entirely different histories.
e1d1138653
...
5626d1eacb
13 changed files with 23 additions and 270 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,5 +2,4 @@
|
||||||
*.asm
|
*.asm
|
||||||
*.o
|
*.o
|
||||||
*.elf
|
*.elf
|
||||||
build
|
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
11
Makefile
11
Makefile
|
@ -7,18 +7,9 @@ build: $(SUBDIRS)
|
||||||
$(MAKE) -j$(nproc) -C $$dir; \
|
$(MAKE) -j$(nproc) -C $$dir; \
|
||||||
done
|
done
|
||||||
|
|
||||||
test: $(SUBDIRS) build
|
|
||||||
@for dir in $(SUBDIRS); do \
|
|
||||||
$(MAKE) -j$(nproc) test -C $$dir; \
|
|
||||||
done
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@for dir in $(SUBDIRS); do \
|
@for dir in $(SUBDIRS); do \
|
||||||
make -C $$dir clean; \
|
make -C $$dir clean; \
|
||||||
done
|
done
|
||||||
|
|
||||||
format:
|
.PHONY: build clean
|
||||||
find . -type f \( -name "*.cpp" -o -name "*.h" -o -name "*.c" \) -exec clang-format -i {} \;
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: build clean test format
|
|
||||||
|
|
|
@ -8,24 +8,3 @@
|
||||||
assert(cond); \
|
assert(cond); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ASSERT_EQ(expected, actual) \
|
|
||||||
do { \
|
|
||||||
if ((expected) != (actual)) { \
|
|
||||||
std::cerr << "Assertion failed: (" #expected " == " #actual ") " \
|
|
||||||
<< "Expected: " << (expected) \
|
|
||||||
<< ", Actual: " << (actual) << "\n"; \
|
|
||||||
assert((expected) == (actual)); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ASSERT_EQMSG(expected, actual, msg) \
|
|
||||||
do { \
|
|
||||||
if ((expected) != (actual)) { \
|
|
||||||
std::cerr << "Assertion failed: " << msg << "\n" \
|
|
||||||
<< "(" #expected " == " #actual ") " \
|
|
||||||
<< "Expected: " << (expected) \
|
|
||||||
<< ", Actual: " << (actual) << "\n"; \
|
|
||||||
assert((expected) == (actual)); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
12
config.mk
12
config.mk
|
@ -4,22 +4,12 @@ MAKEFLAGS += --no-print-directory
|
||||||
.PRECIOUS: %.o
|
.PRECIOUS: %.o
|
||||||
.PRECIOUS: %.asm
|
.PRECIOUS: %.asm
|
||||||
|
|
||||||
TARGET ?= main.elf
|
|
||||||
SRCS ?= $(wildcard *.cc)
|
|
||||||
HDRS ?= $(wildcard *.h)
|
|
||||||
|
|
||||||
OBJS = $(SRCS:.cc=.o)
|
OBJS = $(SRCS:.cc=.o)
|
||||||
ASMS = $(SRCS:.cc=.asm)
|
ASMS = $(SRCS:.cc=.asm)
|
||||||
|
|
||||||
all: $(TARGET) $(ASMS)
|
all: $(TARGET) $(ASMS)
|
||||||
$(TARGET): $(OBJS)
|
$(TARGET): $(OBJS)
|
||||||
|
|
||||||
test: $(TARGET)
|
|
||||||
./$(TARGET)
|
|
||||||
|
|
||||||
check: $(SRCS) $(HDRS)
|
|
||||||
cppcheck --language=c++ $^
|
|
||||||
|
|
||||||
asm: $(ASMS)
|
asm: $(ASMS)
|
||||||
|
|
||||||
%.o: %.cc
|
%.o: %.cc
|
||||||
|
@ -37,4 +27,4 @@ asm: $(ASMS)
|
||||||
clean:
|
clean:
|
||||||
rm -f *.elf *.asm *.o
|
rm -f *.elf *.asm *.o
|
||||||
|
|
||||||
.PHONY: clean all asm check test
|
.PHONY: clean all asm
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
using std::cin;
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
std::string s;
|
|
||||||
|
|
||||||
while (cin >> s, s.length() > 5) {
|
|
||||||
cout << s << " is longer than 5\n";
|
|
||||||
}
|
|
||||||
cout << s << " is too short\n";
|
|
||||||
|
|
||||||
for (int i = 0, j = 0; i != 5; ++i, ++j) {
|
|
||||||
cout << i << ", " << j << endl;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include <fstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
void print_bytes(std::string infile) {
|
|
||||||
std::ifstream in{infile};
|
|
||||||
|
|
||||||
int c;
|
|
||||||
while ((c = in.get()) != EOF) {
|
|
||||||
std::cout << "read: " << std::setw(3) << c << " [" << char(c) << "]"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc != 2) {
|
|
||||||
std::cout << "Usage: " << argv[0] << " filename" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_bytes(argv[1]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
using std::cin;
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
void test_map() {
|
|
||||||
std::map<std::string, int> msi;
|
|
||||||
|
|
||||||
msi.insert(std::make_pair("Kalle", 1));
|
|
||||||
msi.emplace("Lisa", 2);
|
|
||||||
msi["Kim"] = 3;
|
|
||||||
|
|
||||||
for (const auto &a : msi) {
|
|
||||||
cout << a.first << " : " << a.second << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "Kim --> " << msi.at("Kim") << endl;
|
|
||||||
cout << "Lisa --> " << msi["Lisa"] << endl;
|
|
||||||
cout << "Hans --> " << msi["Hans"]
|
|
||||||
<< endl; // [] default-konstruerar ett värde
|
|
||||||
// för nycklar som inte finns
|
|
||||||
try {
|
|
||||||
cout << "Nisse --> " << msi.at("Nisse") << endl;
|
|
||||||
} catch (std::out_of_range &e) {
|
|
||||||
cout << "Nisse not found: " << e.what() << endl;
|
|
||||||
}
|
|
||||||
const auto &kim = msi.find("Kim");
|
|
||||||
if (kim != msi.end()) {
|
|
||||||
cout << "Kim : " << kim->second << endl;
|
|
||||||
} else {
|
|
||||||
cout << "Kim not found\n";
|
|
||||||
}
|
|
||||||
auto nisse = msi.find("Nisse");
|
|
||||||
if (nisse != msi.end()) {
|
|
||||||
cout << "Nisse : " << nisse->second << endl;
|
|
||||||
} else {
|
|
||||||
cout << "Nisse not found\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_set() {
|
|
||||||
std::set<int> ints{1, 3, 7};
|
|
||||||
|
|
||||||
ints.insert(5);
|
|
||||||
|
|
||||||
for (auto x : ints) {
|
|
||||||
cout << x << " ";
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
auto has_one = ints.find(1);
|
|
||||||
|
|
||||||
if (has_one != ints.end()) {
|
|
||||||
cout << "one is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "one is not in the set\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ints.count(1)) {
|
|
||||||
cout << "one is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "one is not in the set\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto has_two = ints.find(2);
|
|
||||||
|
|
||||||
if (has_two != ints.end()) {
|
|
||||||
cout << "two is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "two is not in the set\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ints.count(2)) {
|
|
||||||
cout << "two is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "two is not in the set\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto has_five = ints.find(5);
|
|
||||||
|
|
||||||
if (has_five != ints.end()) {
|
|
||||||
cout << "five is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "five is not in the set\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
ints.erase(5);
|
|
||||||
|
|
||||||
auto has_five_now = ints.find(5);
|
|
||||||
|
|
||||||
if (has_five_now != ints.end()) {
|
|
||||||
cout << "five is in the set\n";
|
|
||||||
} else {
|
|
||||||
cout << "five is not in the set\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_set_bounds() {
|
|
||||||
std::set<int> ints{9, 1, 3, 7, 5};
|
|
||||||
|
|
||||||
auto lb3 = ints.lower_bound(3);
|
|
||||||
cout << "lb3: " << *lb3 << endl;
|
|
||||||
auto ub3 = ints.upper_bound(3);
|
|
||||||
cout << "ub3: " << *ub3 << endl;
|
|
||||||
auto lb4 = ints.lower_bound(4);
|
|
||||||
cout << "lb4: " << *lb4 << endl;
|
|
||||||
auto ub4 = ints.upper_bound(4);
|
|
||||||
cout << "ub4: " << *ub4 << endl;
|
|
||||||
auto er = ints.equal_range(7);
|
|
||||||
if (er.first == er.second) {
|
|
||||||
cout << "er.first == er.second";
|
|
||||||
}
|
|
||||||
cout << ", er.first: " << *er.first << ", er.second: " << *er.second
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
test_map();
|
|
||||||
test_set();
|
|
||||||
test_set_bounds();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#ifndef PRINT_SEQ_H
|
|
||||||
#define PRINT_SEQ_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
template <typename C> void print_seq(const C &c) {
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
cout << "[length: " << c.size() << "] ";
|
|
||||||
for (const auto &x : c) std::cout << x << " ";
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
int a{1234};
|
|
||||||
float f{1234.0};
|
|
||||||
|
|
||||||
std::cout << "sizeof(int): " << sizeof(int)
|
|
||||||
<< ", sizeof(float): " << sizeof(float) << std::endl;
|
|
||||||
|
|
||||||
std::cout << "static_cast: " << static_cast<float>(a) << " "
|
|
||||||
<< static_cast<int>(f) << std::endl;
|
|
||||||
|
|
||||||
std::cout << "reinterpret_cast: " << *reinterpret_cast<float *>(&a) << " "
|
|
||||||
<< *reinterpret_cast<int *>(&f) << std::endl;
|
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
TARGET = takewhile.elf
|
TARGET = takewhile.elf
|
||||||
SRCS = takewhile.cc
|
SRCS = takewhile.cc
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
include ../config.mk
|
include ../config.mk
|
||||||
|
|
|
@ -9,26 +9,21 @@ int main() {
|
||||||
|
|
||||||
Vec v;
|
Vec v;
|
||||||
v.push_back(10);
|
v.push_back(10);
|
||||||
int a = v[0];
|
ASSERT_MSG(v[0] == 10, "10 should be present at index 0");
|
||||||
ASSERT_EQMSG(10, a, "10 should be present at index 0");
|
|
||||||
|
|
||||||
Vec v2{1, 2, 3};
|
Vec v2{1, 2, 3};
|
||||||
ASSERT_EQ(3, v2.size());
|
ASSERT_MSG(v2.size() == 3, "Size should be three");
|
||||||
ASSERT_EQMSG(v2.size(), 3, "Size should be three");
|
|
||||||
v2.pop_back();
|
v2.pop_back();
|
||||||
ASSERT_EQ(2, v2.size());
|
|
||||||
ASSERT_MSG(v2.size() == 2, "Size should be three");
|
ASSERT_MSG(v2.size() == 2, "Size should be three");
|
||||||
|
|
||||||
// Triggers a reallocation (memcpy)
|
// Triggers a reallocation (memcpy)
|
||||||
Vec v3{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
Vec v3{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
ASSERT_MSG(v3[11] == 12, "Index 11 should hold 12");
|
ASSERT_MSG(v3[11] == 12, "Index 11 should hold 12");
|
||||||
ASSERT_MSG(v3[5] == 6, "Index 5 should hold 6"); // ???
|
// ASSERT_MSG(v3[5] == 6, "Index 5 should hold 6"); // ???
|
||||||
ASSERT_EQ(12, v3.size());
|
ASSERT_MSG(v3.size() == 12, "Size should be 12");
|
||||||
ASSERT_EQ(24, v3.capacity());
|
ASSERT_MSG(v3.capacity() == 20, "Capacity should be 20");
|
||||||
|
|
||||||
Vec v_sized(40);
|
for (const auto &a : v3) {
|
||||||
v_sized.push_back(0);
|
std::cout << a << std::endl;
|
||||||
ASSERT_MSG(v_sized[0] == 0, "Well");
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
Vec::Vec() : Vec(INITIAL_LEN) {}
|
Vec::Vec() : cap(INITIAL_LEN), w_idx(0), arr(nullptr) {
|
||||||
|
std::cout << "Allocating vector" << std::endl;
|
||||||
Vec::Vec(std::size_t size) : cap(size), w_idx(0), arr(new T[size]) {
|
arr = new T[INITIAL_LEN];
|
||||||
std::cout << "Allocating vector of size " << size << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec::Vec(std::initializer_list<T> il) : Vec(il.size()) {
|
Vec::Vec(std::initializer_list<T> il) : Vec() {
|
||||||
for (auto &elem : il) push_back(std::move(elem));
|
for (auto &a : il) push_back(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec::~Vec() {
|
Vec::~Vec() {
|
||||||
|
@ -27,18 +26,12 @@ T &Vec::operator[](std::size_t idx) const noexcept {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vec::push_back(const T &value) {
|
void Vec::push_back(const T &value) noexcept {
|
||||||
arr[w_idx++] = value;
|
arr[w_idx++] = value;
|
||||||
|
|
||||||
if (w_idx == cap)
|
if (w_idx == cap) {
|
||||||
resize(cap * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vec::push_back(T &&value) {
|
|
||||||
arr[w_idx++] = std::move(value);
|
|
||||||
|
|
||||||
if (w_idx == cap)
|
|
||||||
resize(cap * 2);
|
resize(cap * 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t Vec::size() const { return w_idx; }
|
std::size_t Vec::size() const { return w_idx; }
|
||||||
|
@ -46,10 +39,9 @@ std::size_t Vec::size() const { return w_idx; }
|
||||||
std::size_t Vec::capacity() const noexcept { return cap; }
|
std::size_t Vec::capacity() const noexcept { return cap; }
|
||||||
|
|
||||||
void Vec::resize(std::size_t newsize) {
|
void Vec::resize(std::size_t newsize) {
|
||||||
std::cout << "Reallocating: " << cap << " to " << newsize << std::endl;
|
std::cout << "Reallocating" << std::endl;
|
||||||
|
|
||||||
T *newarr = new T[newsize];
|
T *newarr = new T[newsize];
|
||||||
std::move(arr, arr + w_idx, newarr);
|
std::memcpy(newarr, arr, w_idx);
|
||||||
delete[] arr;
|
delete[] arr;
|
||||||
arr = newarr;
|
arr = newarr;
|
||||||
cap = newsize;
|
cap = newsize;
|
||||||
|
|
|
@ -13,7 +13,6 @@ class Vec {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Vec();
|
Vec();
|
||||||
explicit Vec(std::size_t);
|
|
||||||
Vec(std::initializer_list<T>);
|
Vec(std::initializer_list<T>);
|
||||||
Vec(const Vec &other); // Copy
|
Vec(const Vec &other); // Copy
|
||||||
Vec(Vec &&other) noexcept; // Move
|
Vec(Vec &&other) noexcept; // Move
|
||||||
|
@ -26,8 +25,7 @@ class Vec {
|
||||||
std::size_t size() const;
|
std::size_t size() const;
|
||||||
std::size_t capacity() const noexcept;
|
std::size_t capacity() const noexcept;
|
||||||
|
|
||||||
void push_back(const T &value); // May except
|
void push_back(const T &value) noexcept;
|
||||||
void push_back(T &&value);
|
|
||||||
void pop_back() noexcept;
|
void pop_back() noexcept;
|
||||||
void clear() noexcept;
|
void clear() noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue