#include #include #include #include #include #include #include #include using namespace _cow_util; /// UTF8 multibyte 4. struct utf8_t { const static constexpr size_t MULTIBYTE =4; typedef std::array Unicode; constexpr inline utf8_t() { data[0] = 0; } template constexpr inline utf8_t(const char (&buffer)[N]) { static_assert(N<=MULTIBYTE, "Expected multibyte 4"); data = { buffer[0], buffer[1], buffer[2], buffer[3], 0, }; } constexpr inline utf8_t(char ascii) { data[0] = ascii; data[1] = 0; } constexpr inline utf8_t(const char* c) { for(size_t i=0;ibelow = nullptr; if(right) right->left = nullptr; if(below) below->above = nullptr; if(left) left->right = nullptr; } private: size_t id; //TODO //Cow raw_tiles; //Cow taw_graphics; // Links will be NULL if there is no loaded segment in their position. // The objects themselves live in Map's segment registry (seg_reg). Segment* above; Segment* right; Segment* below; Segment* left; }; struct Map { // Remove a registered Segment. Resetting its neighbours' links if needed. // The reference will be invalid after calling this function. void unregister_segment(Segment& segment) { if(segment.id seg_reg; }; } template void print_slice(Slice memory) { printf("slice: { %p, %lu (%lu bytes) }\n", memory.ptr(), memory.size(), memory.size_bytes()); } void write_fake(Cow& clone, const char* string) { strncpy(clone.area_as(), string, clone.size_as()-1); } void read_fake(const Cow& clone) { printf("read_fake: %s\n", clone.area_as()); } void moving_cow(Cow moved) { auto moved_clone = moved.reinterpret(); strncpy(&moved_clone, "Ummmm....", moved_clone.size()); read_fake(moved); } void typed_cow() { TypedCow tc(1024); } int main() { Cow _area(4000); Area area = std::move(_area); 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); memset(real, 0, real.size_bytes()); printf("Created real: "); print_slice(real); print_slice(real.slice_wrap(-20, -10)); write_fake(real, "Hello world"); read_fake(real); Cow::Fake clone = real; printf("Fake size: %lu\n", clone.size()); printf("Fake ptr: %p\n", clone.ptr()); read_fake(clone); write_fake(clone, "hello fake!"); read_fake(clone); read_fake(real); printf("First byte of: real = %x, fake = %x\n", real[0], clone[0]); moving_cow(std::move(real)); //moving real is fine // <-- real is now dropped. But `clone` still holds Rc to _inner (cow_t). printf("First byte of: fake = %x\n", clone[0]); read_fake(clone); //clone still functions because of refcount on origin. typed_cow(); printf("Last error: %d, %s\n", cow_err(), *cow_err_msg(cow_err())); try { Cow should_fail(SIZE_MAX); Cow::Fake should_fail_clone = should_fail; } catch (CowException& cw) { printf("Error! (%d) %s\n", cw.kind, cw.what()); } printf("Last error: %d, %s\n", cow_err(), *cow_err_msg(cow_err())); return 0; }