diff --git a/Makefile b/Makefile index f2a9371..a411c8b 100644 --- a/Makefile +++ b/Makefile @@ -69,6 +69,11 @@ all: | clean .PHONY: install .PHONY: uninstall +.PHONY: test +test: + @rm -f $(PROJECT)-cpp-test + @$(MAKE) $(PROJECT)-cpp-test + # Targets dirs: @@ -130,3 +135,7 @@ uninstall: -rm $(DESTDIR)$(PREFIX)/lib/lib$(PROJECT).{a,so} cd $(INCLUDE) && find . -type f | xargs -I {} rm "$(DESTDIR)$(PREFIX)/include/{}" -rmdir $(DESTDIR)$(PREFIX)/include/$(PROJECT) + +$(PROJECT)-cpp-test: lib$(PROJECT).a + g++ -O3 --std=gnu++20 -Iinclude/ -g -Wall -Wextra src/test/*.cpp -o $@ -l:$< + valgrind ./$@ diff --git a/include/cow/area.hpp b/include/cow/area.hpp new file mode 100644 index 0000000..8c204ef --- /dev/null +++ b/include/cow/area.hpp @@ -0,0 +1,28 @@ +// `Area` is a copyable type that opaquely represents either `Cow` or `Cow::Fake`. +#pragma once + +#include +#include + +#include + +struct Area { + Area(size_t sz); + Area(const Area& area); + Area(Area&& area); + + inline const Cow* operator->() const { return _area.get(); } + inline Cow* operator->() { return _area.get(); } + + inline const Cow* operator*() const { return _area.get(); } + inline Cow* operator*() { return _area.get(); } + + inline operator const Cow&() const { return *_area.get(); } + inline operator Cow&() { return *_area.get(); } + + inline bool is_clone() const { return dynamic_cast(_area.get()) != nullptr; } + + ~Area(); + private: + const std::unique_ptr _area; +}; diff --git a/src/area.cpp b/src/area.cpp new file mode 100644 index 0000000..af42b58 --- /dev/null +++ b/src/area.cpp @@ -0,0 +1,8 @@ +#include + +Area::Area(size_t sz) : _area(std::make_unique(sz)){} +Area::Area(const Area& copy) : + _area(std::make_unique(*copy._area.get())){} +Area::Area(Area&& move) : + _area(std::move(*const_cast*>(&move._area))){} +Area::~Area(){} diff --git a/src/test/main.cpp b/src/test/main.cpp index 5c8cada..25c3d44 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace _cow_util; /// UTF8 multibyte 4. @@ -35,7 +37,7 @@ struct utf8_t { } constexpr inline utf8_t(const char* c) { - for(int i=0;i void print_slice(Slice memory) { @@ -165,11 +170,23 @@ void moving_cow(Cow moved) int main() { + Area area(4000); + write_fake(area, "Hello???"); + Area area2 = area; + write_fake(area2, "Hi"); + Area area3 = std::move(area2); + Area area4 = std::move(area); + read_fake(area3); + read_fake(area4); + + printf("Is clone: a1: %d, a2: %d\n", area4.is_clone(), area3.is_clone()); + utf8_t ch = "あ"; utf8_t ch2('a'); utf8_t ch3 = ch.c_str(); utf8_t ch4 = ch3.data; utf8_t ch5 = ch4; + (void)ch5; printf("Test: %s, %s, %s\n", (const char*)ch, ch2.c_str(), ch3.c_str()); Cow real(4096);