From 5626d1eacb04ca9367de5322161fbac3db9a1059 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Fri, 10 Jan 2025 08:15:31 +0100 Subject: [PATCH] dump --- .clang-format | 7 +++++ .gitignore | 5 ++++ CMakeLists.txt | 8 ++++++ Makefile | 15 ++++++++++ common/CMakeLists.txt | 8 ++++++ common/iassert.h | 10 +++++++ config.mk | 30 ++++++++++++++++++++ junk/1.5.cc | 27 ++++++++++++++++++ junk/1.cc | 63 ++++++++++++++++++++++++++++++++++++++++++ junk/2.cc | 19 +++++++++++++ junk/3.cc | 45 ++++++++++++++++++++++++++++++ junk/4.cc | 38 +++++++++++++++++++++++++ junk/class.cc | 12 ++++++++ takewhile/Makefile | 6 ++++ takewhile/takewhile.cc | 54 ++++++++++++++++++++++++++++++++++++ tent1/Makefile | 6 ++++ tent1/main.cc | 5 ++++ tent2/Makefile | 6 ++++ tent2/main.cc | 5 ++++ vector/CMakeLists.txt | 7 +++++ vector/Makefile | 4 +++ vector/main.cc | 29 +++++++++++++++++++ vector/vec.cc | 60 ++++++++++++++++++++++++++++++++++++++++ vector/vec.h | 43 ++++++++++++++++++++++++++++ 24 files changed, 512 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 Makefile create mode 100644 common/CMakeLists.txt create mode 100644 common/iassert.h create mode 100644 config.mk create mode 100644 junk/1.5.cc create mode 100644 junk/1.cc create mode 100644 junk/2.cc create mode 100644 junk/3.cc create mode 100644 junk/4.cc create mode 100644 junk/class.cc create mode 100644 takewhile/Makefile create mode 100644 takewhile/takewhile.cc create mode 100644 tent1/Makefile create mode 100644 tent1/main.cc create mode 100644 tent2/Makefile create mode 100644 tent2/main.cc create mode 100644 vector/CMakeLists.txt create mode 100644 vector/Makefile create mode 100644 vector/main.cc create mode 100644 vector/vec.cc create mode 100644 vector/vec.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5364839 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +# Language: C +BasedOnStyle: LLVM +IndentWidth: 4 # Use 4 spaces for indentation +TabWidth: 4 # Tab width is also 4 spaces +UseTab: Never # Always use spaces instead of tabs +ColumnLimit: 80 # Wrap lines after 80 characters +AllowShortLoopsOnASingleLine: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e899e11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.cache +*.asm +*.o +*.elf +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1b2800b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(SuperProject) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_subdirectory(common) +add_subdirectory(vector) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0ea4232 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +# SUBDIRS = dir1 dir2 dir3 +SUBDIRS := $(shell find . -mindepth 1 -maxdepth 1 -type d -exec test -e "{}/Makefile" \; -print) + + +build: $(SUBDIRS) + @for dir in $(SUBDIRS); do \ + $(MAKE) -j$(nproc) -C $$dir; \ + done + +clean: + @for dir in $(SUBDIRS); do \ + make -C $$dir clean; \ + done + +.PHONY: build clean diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000..7de93f1 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.16) +project(Common) + +add_library(common INTERFACE) + +target_include_directories(common INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/common/iassert.h b/common/iassert.h new file mode 100644 index 0000000..841a806 --- /dev/null +++ b/common/iassert.h @@ -0,0 +1,10 @@ +#include +#include + +#define ASSERT_MSG(cond, msg) \ + do { \ + if (!(cond)) { \ + std::cerr << "Assertion failed: " << msg << "\n"; \ + assert(cond); \ + } \ + } while (0) diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..70b49ee --- /dev/null +++ b/config.mk @@ -0,0 +1,30 @@ +CXXFLAGS ?= -Wall -Wextra -O2 -g0 -std=c++23 -I../common/ +MAKEFLAGS += --no-print-directory + +.PRECIOUS: %.o +.PRECIOUS: %.asm + +OBJS = $(SRCS:.cc=.o) +ASMS = $(SRCS:.cc=.asm) + +all: $(TARGET) $(ASMS) +$(TARGET): $(OBJS) + +asm: $(ASMS) + +%.o: %.cc + @echo CC $@ + @g++ $(CXXFLAGS) -c $< -o $@ + +%.asm: %.o + @echo DEC $@ + @objdump -d -M intel $< > $@ + +%.elf: %.o | %.asm + @echo CC/LD $@ + @g++ $(CXXFLAGS) -o $@ $^ + +clean: + rm -f *.elf *.asm *.o + +.PHONY: clean all asm diff --git a/junk/1.5.cc b/junk/1.5.cc new file mode 100644 index 0000000..6321ecd --- /dev/null +++ b/junk/1.5.cc @@ -0,0 +1,27 @@ +#include + +using std::cout; + +struct A { + A() = default; + A(int x) { val = x; } + void print() { cout << "A(" << val << ")"; } + int val; +}; + +struct B { + // B(int x) { a = A(x); } + B(int x) : a(x) {} + void print() { + cout << "B("; + a.print(); + cout << ")"; + } + A a; +}; + +int main() { + B b(10); + b.print(); + cout << "\n"; +} diff --git a/junk/1.cc b/junk/1.cc new file mode 100644 index 0000000..6e3f30b --- /dev/null +++ b/junk/1.cc @@ -0,0 +1,63 @@ +#include + +using std::cout; + +// Rule of three: +// If a class requires a user-defined destructor, a user-defined copy +// constructor, or a user-defined copy assignment operator, it almost certainly +// requires all three. +// + +// Rule of five: +// Because the presence of a user-defined (include = default or = delete +// declared) destructor, copy-constructor, or copy-assignment operator prevents +// implicit definition of the move constructor and the move assignment operator, +// any class for which move semantics are desirable, has to declare all five +// special member functions: + +struct A { + A() = default; + /* Constructor */ + A(const int &x) { val = x; } + /* Copy constructor */ + A(A &other) { other.val = this->val; } + /* Move constructor */ + A(A &&other) { other.val = this->val; } + /* Copy assignment operator */ + A &operator=(const A &other) { return *this; } + ~A() {} + void print() { cout << "A(" << val << ")"; } + int val; +}; + +struct B { + B(int x) { a = A(x); } + // B(int x) : a(x) {}; + void print() { + cout << "B("; + a.print(); + cout << ")"; + } + A a; +}; + +int main() { + B b(10); + b.print(); + cout << "\n"; +} + +struct K { + K() = default; + /* Constructor */ + K(const int &x) { val = x; } + /* Copy constructor */ + K(K &other) : K(other.val) {} + /* Move constructor */ + K(K &&other) : K(other.val) {} + /* Copy assignment operator */ + K &operator=(const K &other) { return *this; } + ~K() {} + void print() { cout << "K(" << val << ")"; } + int val; +}; diff --git a/junk/2.cc b/junk/2.cc new file mode 100644 index 0000000..d542b69 --- /dev/null +++ b/junk/2.cc @@ -0,0 +1,19 @@ +#include +#include + +void consume_number(int *p) { + std::cout << "Consuming: " << *p << std::endl; + delete p; +} + +void random_int(int &out) { out = rand(); } + +void use2() { + int i; + random_int(i); + consume_number(&i); +} + +int main(int argc, char *argv[]) { + use2(); +} diff --git a/junk/3.cc b/junk/3.cc new file mode 100644 index 0000000..e9adfbe --- /dev/null +++ b/junk/3.cc @@ -0,0 +1,45 @@ +#include +#include + +// In C we need a length in bytes to check for equality +void compareObject(void *a, void *b, size_t len) { + if (a == b) + std::cout << "Same address" << std::endl; + + // Being explicit about pointer type allows pointer arithmetic + unsigned char *i1 = (unsigned char *)a; + unsigned char *i2 = (unsigned char *)b; + + for (size_t i = 0; i < len; i++) { + if (i1[i] != i2[i]) { + std::cout << "Different value" << std::endl; + return; + } + } + + std::cout << "Same value" << std::endl; +} + +template void cmp(T &a, T &b) { + if (&a == &b) + std::cout << "Same object" << std::endl; + + if (a == b) + std::cout << "Same value" << std::endl; + else + std::cout << "Different value" << std::endl; +} + +int main() { + int a = 10, b = 10, c = 12; + + std::cout << "Checking template version" << std::endl; + + cmp(a, b); + cmp(a, c); + + std::cout << "Checking C version" << std::endl; + + compareObject(&a, &b, sizeof(int)); + compareObject(&a, &c, sizeof(int)); +} diff --git a/junk/4.cc b/junk/4.cc new file mode 100644 index 0000000..f99c9f8 --- /dev/null +++ b/junk/4.cc @@ -0,0 +1,38 @@ +#include +#include +#include + +template +std::pair copy_while(InputIt first, InputIt last, + OutputIt out, Pred p); + +std::vector take_while_sum_less_than(std::vector &v, int n) { + std::vector out; + int acc = 0; + while (true) { + if (v.back() + acc > n) { + int next = v.back(); + out.push_back(n); + v.pop_back(); + } + } +} + +#if __cplusplus > 202002L +// #include +// #include + +std::vector take_while_sum_less_than(const std::vector &v, int n) { + int sum = 0; + + auto result = v | std::ranges::views::take_while([&sum, n](int x) { + if (sum + x < n) { + sum += x; + return true; + } + return false; + }); + + return std::vector(result.begin(), result.end()); +} +#endif diff --git a/junk/class.cc b/junk/class.cc new file mode 100644 index 0000000..75817d7 --- /dev/null +++ b/junk/class.cc @@ -0,0 +1,12 @@ +#include +template class User { + T id; + +public: + explicit User(T n) : id(n) {} +}; + +int main() { + User user1{1}; + User user2(0xFF); +} diff --git a/takewhile/Makefile b/takewhile/Makefile new file mode 100644 index 0000000..367bb06 --- /dev/null +++ b/takewhile/Makefile @@ -0,0 +1,6 @@ +TARGET = takewhile.elf +SRCS = takewhile.cc + +all: $(TARGET) + +include ../config.mk diff --git a/takewhile/takewhile.cc b/takewhile/takewhile.cc new file mode 100644 index 0000000..b908ac4 --- /dev/null +++ b/takewhile/takewhile.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include + +template +std::pair copy_while(InputIt first, InputIt last, + OutputIt out, Pred p) { + // Iterate through the input range + while (first != last && p(*first)) { + *out = *first; // Copy the value to the output + ++first; // Move to the next input element + ++out; // Move to the next output element + } + // Return the pair of iterators + return {first, out}; +} + +std::vector take_while_sum_less_than(std::vector &invec, int n) { + std::vector out; + int sum = 0; + copy_while(invec.begin(), invec.end(), std::back_inserter(out), + [&](int &x) -> bool { return (sum += x) < n; }); + return out; +} + +int main() { + // Sample data + std::vector input = {1, 2, 3, 6, + 7, 8}; // We will stop copying when we encounter 6 + std::vector output; + + // Define the predicate: copy while the value is <= 5 + auto pred = [](int n) { return n <= 5; }; + + // Call copy_while with the test data + auto [new_first, new_out] = copy_while(input.begin(), input.end(), + std::back_inserter(output), pred); + + // Assert that the copied elements are correct (only the first three + // elements) + std::vector test = std::vector{1, 2, 3}; + assert(output == test); + + // Assert that the iterator returned points to the element that did not + // match the predicate (6) + assert(*new_first == 6); + + std::vector v{1, 2, 3}; + auto w = take_while_sum_less_than(v, 10); + std::cout << "Hello" << std::endl; + std::for_each(w.begin(), w.end(), + [](int &a) { std::cout << a << " " << std::endl; }); +} diff --git a/tent1/Makefile b/tent1/Makefile new file mode 100644 index 0000000..1d058e2 --- /dev/null +++ b/tent1/Makefile @@ -0,0 +1,6 @@ +TARGET = main.elf +SRCS = main.cc + +all: $(TARGET) + +include ../config.mk diff --git a/tent1/main.cc b/tent1/main.cc new file mode 100644 index 0000000..f9967ce --- /dev/null +++ b/tent1/main.cc @@ -0,0 +1,5 @@ +#include + +int main() { + std::cout << "Hola" << std::endl; +} diff --git a/tent2/Makefile b/tent2/Makefile new file mode 100644 index 0000000..1d058e2 --- /dev/null +++ b/tent2/Makefile @@ -0,0 +1,6 @@ +TARGET = main.elf +SRCS = main.cc + +all: $(TARGET) + +include ../config.mk diff --git a/tent2/main.cc b/tent2/main.cc new file mode 100644 index 0000000..f9967ce --- /dev/null +++ b/tent2/main.cc @@ -0,0 +1,5 @@ +#include + +int main() { + std::cout << "Hola" << std::endl; +} diff --git a/vector/CMakeLists.txt b/vector/CMakeLists.txt new file mode 100644 index 0000000..9f156c1 --- /dev/null +++ b/vector/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.16) +project(vec) + +add_executable(main main.cc vec.cc) + +# Link the common library +target_link_libraries(main PRIVATE common) diff --git a/vector/Makefile b/vector/Makefile new file mode 100644 index 0000000..617f3f2 --- /dev/null +++ b/vector/Makefile @@ -0,0 +1,4 @@ +TARGET = main.elf +SRCS = vec.cc main.cc + +include ../config.mk diff --git a/vector/main.cc b/vector/main.cc new file mode 100644 index 0000000..45717a2 --- /dev/null +++ b/vector/main.cc @@ -0,0 +1,29 @@ +#include "iassert.h" +#include "vec.h" + +int main() { + { + Vec *v = new Vec(); + delete v; + } + + Vec v; + v.push_back(10); + ASSERT_MSG(v[0] == 10, "10 should be present at index 0"); + + Vec v2{1, 2, 3}; + ASSERT_MSG(v2.size() == 3, "Size should be three"); + v2.pop_back(); + ASSERT_MSG(v2.size() == 2, "Size should be three"); + + // Triggers a reallocation (memcpy) + 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[5] == 6, "Index 5 should hold 6"); // ??? + ASSERT_MSG(v3.size() == 12, "Size should be 12"); + ASSERT_MSG(v3.capacity() == 20, "Capacity should be 20"); + + for (const auto &a : v3) { + std::cout << a << std::endl; + } +} diff --git a/vector/vec.cc b/vector/vec.cc new file mode 100644 index 0000000..2df75a8 --- /dev/null +++ b/vector/vec.cc @@ -0,0 +1,60 @@ +#include "vec.h" +#include +#include +#include + +Vec::Vec() : cap(INITIAL_LEN), w_idx(0), arr(nullptr) { + std::cout << "Allocating vector" << std::endl; + arr = new T[INITIAL_LEN]; +} + +Vec::Vec(std::initializer_list il) : Vec() { + for (auto &a : il) push_back(a); +} + +Vec::~Vec() { + std::cout << "De-allocating vector" << std::endl; + + if (arr) + delete[] arr; +} + +T &Vec::operator[](std::size_t idx) const noexcept { + if (idx < w_idx) + return arr[idx]; + + exit(1); +} + +void Vec::push_back(const T &value) noexcept { + arr[w_idx++] = value; + + if (w_idx == cap) { + resize(cap * 2); + } +} + +std::size_t Vec::size() const { return w_idx; } + +std::size_t Vec::capacity() const noexcept { return cap; } + +void Vec::resize(std::size_t newsize) { + std::cout << "Reallocating" << std::endl; + T *newarr = new T[newsize]; + std::memcpy(newarr, arr, w_idx); + delete[] arr; + arr = newarr; + cap = newsize; +} + +void Vec::pop_back() noexcept { --w_idx; } + +void Vec::clear() noexcept { +#ifdef REALCLEAR + delete[] arr; + arr = new T[INITIAL_LEN]; + cap = INITIAL_LEN; +#endif + + w_idx = 0; +} diff --git a/vector/vec.h b/vector/vec.h new file mode 100644 index 0000000..5154bc7 --- /dev/null +++ b/vector/vec.h @@ -0,0 +1,43 @@ +#include +#include + +typedef int T; +constexpr int INITIAL_LEN = 10; + +class Vec { + std::size_t cap; + std::size_t w_idx; + T *arr = nullptr; + + void resize(std::size_t newsize); + + public: + Vec(); + Vec(std::initializer_list); + Vec(const Vec &other); // Copy + Vec(Vec &&other) noexcept; // Move + Vec &operator=(const Vec &other); // CopyAssign + Vec &operator=(Vec &&other) noexcept; // MoveAssign + ~Vec(); // Destructor + + T &operator[](std::size_t) const noexcept; + + std::size_t size() const; + std::size_t capacity() const noexcept; + + void push_back(const T &value) noexcept; + void pop_back() noexcept; + void clear() noexcept; + + using iterator = T *; + using const_iterator = const T *; + + iterator begin() noexcept { return arr; } + iterator end() noexcept { return arr + w_idx; } + + const_iterator begin() const noexcept { return arr; } + const_iterator end() const noexcept { return arr + w_idx; } +}; + +// std::iterator end() const noexcept; +// std::iterator begin() const noexcept;