dump
This commit is contained in:
commit
5626d1eacb
24 changed files with 512 additions and 0 deletions
7
.clang-format
Normal file
7
.clang-format
Normal file
|
@ -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
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.cache
|
||||||
|
*.asm
|
||||||
|
*.o
|
||||||
|
*.elf
|
||||||
|
compile_commands.json
|
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
|
@ -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)
|
15
Makefile
Normal file
15
Makefile
Normal file
|
@ -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
|
8
common/CMakeLists.txt
Normal file
8
common/CMakeLists.txt
Normal file
|
@ -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}
|
||||||
|
)
|
10
common/iassert.h
Normal file
10
common/iassert.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define ASSERT_MSG(cond, msg) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
std::cerr << "Assertion failed: " << msg << "\n"; \
|
||||||
|
assert(cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
30
config.mk
Normal file
30
config.mk
Normal file
|
@ -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
|
27
junk/1.5.cc
Normal file
27
junk/1.5.cc
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
63
junk/1.cc
Normal file
63
junk/1.cc
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
19
junk/2.cc
Normal file
19
junk/2.cc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
45
junk/3.cc
Normal file
45
junk/3.cc
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// 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 <typename T> 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));
|
||||||
|
}
|
38
junk/4.cc
Normal file
38
junk/4.cc
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
template <typename InputIt, typename OutputIt, typename Pred>
|
||||||
|
std::pair<InputIt, OutputIt> copy_while(InputIt first, InputIt last,
|
||||||
|
OutputIt out, Pred p);
|
||||||
|
|
||||||
|
std::vector<int> take_while_sum_less_than(std::vector<int> &v, int n) {
|
||||||
|
std::vector<int> 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 <ranges>
|
||||||
|
// #include <numeric>
|
||||||
|
|
||||||
|
std::vector<int> take_while_sum_less_than(const std::vector<int> &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<int>(result.begin(), result.end());
|
||||||
|
}
|
||||||
|
#endif
|
12
junk/class.cc
Normal file
12
junk/class.cc
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include <cstdint>
|
||||||
|
template <typename T> class User {
|
||||||
|
T id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit User(T n) : id(n) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
User<int> user1{1};
|
||||||
|
User<uint8_t> user2(0xFF);
|
||||||
|
}
|
6
takewhile/Makefile
Normal file
6
takewhile/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TARGET = takewhile.elf
|
||||||
|
SRCS = takewhile.cc
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
include ../config.mk
|
54
takewhile/takewhile.cc
Normal file
54
takewhile/takewhile.cc
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template <typename InputIt, typename OutputIt, typename Pred>
|
||||||
|
std::pair<InputIt, OutputIt> 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<int> take_while_sum_less_than(std::vector<int> &invec, int n) {
|
||||||
|
std::vector<int> 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<int> input = {1, 2, 3, 6,
|
||||||
|
7, 8}; // We will stop copying when we encounter 6
|
||||||
|
std::vector<int> 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<int> test = std::vector<int>{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<int> 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; });
|
||||||
|
}
|
6
tent1/Makefile
Normal file
6
tent1/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TARGET = main.elf
|
||||||
|
SRCS = main.cc
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
include ../config.mk
|
5
tent1/main.cc
Normal file
5
tent1/main.cc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Hola" << std::endl;
|
||||||
|
}
|
6
tent2/Makefile
Normal file
6
tent2/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TARGET = main.elf
|
||||||
|
SRCS = main.cc
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
include ../config.mk
|
5
tent2/main.cc
Normal file
5
tent2/main.cc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "Hola" << std::endl;
|
||||||
|
}
|
7
vector/CMakeLists.txt
Normal file
7
vector/CMakeLists.txt
Normal file
|
@ -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)
|
4
vector/Makefile
Normal file
4
vector/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
TARGET = main.elf
|
||||||
|
SRCS = vec.cc main.cc
|
||||||
|
|
||||||
|
include ../config.mk
|
29
vector/main.cc
Normal file
29
vector/main.cc
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
60
vector/vec.cc
Normal file
60
vector/vec.cc
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include "vec.h"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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<T> 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;
|
||||||
|
}
|
43
vector/vec.h
Normal file
43
vector/vec.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
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<T>);
|
||||||
|
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<Vec> end() const noexcept;
|
||||||
|
// std::iterator begin() const noexcept;
|
Loading…
Reference in a new issue