├── .cproject ├── .gitignore ├── .project ├── LICENSE ├── Makefile ├── README.md ├── std ├── algorithm.h ├── array.h ├── bits.cpp ├── bits.h ├── boundary.h ├── container.h ├── file.cpp ├── file.h ├── fill.h ├── filter.h ├── graph.h ├── hash_map.h ├── hash_set.cpp ├── hash_set.h ├── heap.h ├── implier.h ├── index_list.h ├── interface.h ├── io.cpp ├── io.h ├── list.h ├── map.h ├── pair.h ├── partite.h ├── range.h ├── search.h ├── slice.h ├── sort.h ├── sparse_range.h ├── stream.cpp ├── stream.h ├── string.cpp └── string.h └── test ├── algorithm.cpp ├── array_iterator.cpp ├── array_struct.cpp ├── bits.cpp ├── fill_iterator.cpp ├── fill_struct.cpp ├── filter.cpp ├── graph_iterator.cpp ├── graph_struct.cpp ├── hash_map_struct.cpp ├── hash_set_iterator.cpp ├── hash_set_struct.cpp ├── heap.cpp ├── implier.cpp ├── index_list_iterator.cpp ├── index_list_struct.cpp ├── list_iterator.cpp ├── list_struct.cpp ├── map.cpp ├── pair.cpp ├── range_iterator.cpp ├── range_struct.cpp ├── search.cpp ├── slice_iterator.cpp ├── slice_struct.cpp ├── sort.cpp ├── sparse_range_iterator.cpp └── sparse_range_struct.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Dependency Files 31 | *.d 32 | 33 | # Misc Files 34 | .settings 35 | test_stdcore 36 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | stdcore 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ned Bingham 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CXXFLAGS = -g -O2 -Wall -fmessage-length=0 -I. 2 | # -g -fprofile-arcs -ftest-coverage 3 | SOURCES := $(wildcard std/*.cpp) 4 | TESTS := $(wildcard test/*.cpp) 5 | OBJECTS := $(SOURCES:%.cpp=%.o) 6 | TEST_OBJECTS := $(TESTS:.cpp=.o) 7 | DEPS := $(OBJECTS:.o=.d) 8 | TEST_DEPS := $(TEST_OBJECTS:.o=.d) 9 | GTEST := ../googletest 10 | GTEST_I := -I$(GTEST)/include -I. 11 | GTEST_L := -L$(GTEST) -L. 12 | TARGET = libstdcore.a 13 | TEST_TARGET = test_stdcore 14 | 15 | -include $(DEPS) 16 | -include $(TEST_DEPS) 17 | 18 | all: lib 19 | 20 | lib: $(TARGET) 21 | 22 | test: lib $(TEST_TARGET) 23 | 24 | check: test 25 | ./$(TEST_TARGET) 26 | 27 | $(TARGET): $(OBJECTS) 28 | ar rvs $(TARGET) $(OBJECTS) 29 | 30 | std/%.o: std/%.cpp 31 | $(CXX) $(CXXFLAGS) -MM -MF $(patsubst %.o,%.d,$@) -MT $@ -c $< 32 | $(CXX) $(CXXFLAGS) -c -o $@ $< 33 | 34 | $(TEST_TARGET): $(TEST_OBJECTS) test/gtest_main.o 35 | $(CXX) $(CXXFLAGS) $(GTEST_L) $^ -pthread -lstdcore -lgtest -o $(TEST_TARGET) 36 | 37 | test/%.o: test/%.cpp 38 | $(CXX) $(CXXFLAGS) $(GTEST_I) -MM -MF $(patsubst %.o,%.d,$@) -MT $@ -c $< 39 | $(CXX) $(CXXFLAGS) $(GTEST_I) $< -c -o $@ 40 | 41 | test/gtest_main.o: $(GTEST)/src/gtest_main.cc 42 | $(CXX) $(CXXFLAGS) $(GTEST_I) $< -c -o $@ 43 | 44 | clean: 45 | rm -f std/*.o test/*.o 46 | rm -f std/*.d test/*.d 47 | rm -f std/*.gcda test/*.gcda 48 | rm -f std/*.gcno test/*.gcno 49 | rm -f $(TARGET) $(TEST_TARGET) 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Standard Core 2 | 3 | Welcome to the Standard Core. This is a library for standard containers and their associated algorithms. 4 | 5 | For thorough documentation, check out the [wiki](https://github.com/nbingham1/stdcore/wiki). 6 | 7 | # Why does this exist? 8 | 9 | I've been working with C++ for over a decade at this point. Every now and then, I would need to do something that the C++ Standard Library couldn't do. So I would make the necessary thing and move on. After a while, I noticed that I had managed to implement a full standard library scattered throughout my code base. So, I pulled it all together into a library, and well... here we are. 10 | 11 | ## Why should I care? 12 | 13 | Quite by accident, this library is an interesting case study of a different programming paradigm. I make no claims that this code is optimized, verified, secured, or stabilized. It is provided as is with no guarantee and no promises. However, the resulting API is simple, clean, and expressive. So let's get started. 14 | 15 | # Linking 16 | 17 | Lets start with a basic program which will include the array header. Every header in this library is found in the `std` directory. Every structure and function are contained within the `core` namespace. 18 | 19 | ```c++ 20 | #include 21 | #include 22 | 23 | using namespace core; 24 | 25 | int main() 26 | { 27 | return 0; 28 | } 29 | ``` 30 | 31 | This can be compiled with the following command. 32 | 33 | ``` 34 | g++ example.cpp -Ipath/to/include -Lpath/to/lib -lstdcore -o example 35 | ``` 36 | 37 | # Paradigms 38 | 39 | This library differs from the C++ Standard Library on a few key paradigms. It is these paradigms that make this library unique. 40 | 41 | ## The Simple Things in Life 42 | 43 | First, while the typical array, list, map, and string containers are still the center of the library, there are also dedicated containers for simpler data. This means fill, range, and sparse_range. 44 | 45 | ```c++ 46 | cout << "fill = " << fill(7, 5) << endl; 47 | cout << "range = " << range(5, 15) << endl; 48 | cout << "sparse_range = " << sparse_range(5, 25, 2) << endl; 49 | ``` 50 | 51 | ``` 52 | fill = {5, 5, 5, 5, 5, 5, 5} 53 | range = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14} 54 | sparse_range = {5, 7, 9, 11, 13, 15, 17, 19, 21, 23} 55 | ``` 56 | 57 | ## Power to the Iterator 58 | 59 | Second, iterators have full power to modify their base structure. This means that iterators can push, pop, drop, replace, append, and swap. These actions can still invalidate other iterators depending upon the container structure. 60 | 61 | ```c++ 62 | array arr = range(0, 10); 63 | cout << "arr = " << arr << endl << endl; 64 | 65 | cout << "arr.at(5).pop(3) = " << arr.at(5).pop(3) << endl; 66 | cout << "arr = " << arr << endl << endl; 67 | 68 | cout << "arr.at(2).push(3)" << endl; 69 | arr.at(2).push(3); 70 | cout << "arr = " << arr << endl << endl; 71 | 72 | cout << "arr.at(3).append(range(2, 8))" << endl; 73 | arr.at(3).append(range(2, 8)); 74 | cout << "arr = " << arr << endl << endl; 75 | 76 | cout << "arr.at(4).replace(3, 10)" << endl; 77 | arr.at(4).replace(3, 10); 78 | cout << "arr = " << arr << endl; 79 | ``` 80 | 81 | ``` 82 | arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 83 | 84 | arr.at(5).pop(3) = {5, 6, 7} 85 | arr = {0, 1, 2, 3, 4, 8, 9} 86 | 87 | arr.at(2).push(3) 88 | arr = {0, 1, 3, 2, 3, 4, 8, 9} 89 | 90 | arr.at(3).append(range(2, 8)) 91 | arr = {0, 1, 3, 2, 3, 4, 5, 6, 7, 2, 3, 4, 8, 9} 92 | 93 | arr.at(4).replace(3, 10) 94 | arr = {0, 1, 3, 2, 10, 6, 7, 2, 3, 4, 8, 9} 95 | ``` 96 | 97 | ## Slice and Dice 98 | 99 | Third, this has a full implementation of slices. You can use any container to slice another container. These slices make the API significantly cleaner and easier to use while introducing very little run-time overhead. 100 | 101 | ```c++ 102 | array arr = range(0, 10); 103 | cout << "arr = " << arr << endl << endl; 104 | 105 | slice::iterator> > slc = arr.sub(2, 6); 106 | cout << "slc = " << slc << endl << endl; 107 | 108 | cout << "slc[1] = 100" << endl; 109 | slc[1] = 100; 110 | cout << "slc = " << slc << endl; 111 | cout << "arr = " << arr << endl << endl; 112 | 113 | slice::iterator> > slc2 = array_t(4, 2, 5, 0, 1).sample(arr); 114 | cout << "slc2 = " << slc2 << endl << endl; 115 | 116 | cout << "slc2[1] = 200" << endl; 117 | slc2[1] = 200; 118 | cout << "slc2 = " << slc2 << endl; 119 | cout << "arr = " << arr << endl; 120 | cout << "slc = " << slc << endl; 121 | ``` 122 | 123 | ``` 124 | arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 125 | 126 | slc = {2, 3, 4, 5} 127 | 128 | slc[1] = 100 129 | slc = {2, 100, 4, 5} 130 | arr = {0, 1, 2, 100, 4, 5, 6, 7, 8, 9} 131 | 132 | slc2 = {2, 5, 0, 1} 133 | 134 | slc2[1] = 200 135 | slc2 = {2, 200, 0, 1} 136 | arr = {0, 1, 2, 100, 4, 200, 6, 7, 8, 9} 137 | slc = {2, 100, 4, 200} 138 | ``` 139 | 140 | ## Simplicity Breeds Sanity 141 | 142 | All algorithmic functions like sort, unique, reverse, etc can be run either in place or on a copy of the container in line. 143 | 144 | ```c++ 145 | array arr = array_t(10, 2, 6, 3, 2, 7, 3, 7, 5, 1, 0); 146 | cout << "arr = " << arr << endl << endl; 147 | 148 | cout << "sort_quick(arr) = " << sort_quick(arr) << endl; 149 | cout << "arr = " << arr << endl << endl; 150 | 151 | cout << "sort_quick_inplace(arr)" << endl; 152 | sort_quick_inplace(arr); 153 | cout << "arr = " << arr << endl; 154 | ``` 155 | 156 | ``` 157 | arr = {2, 6, 3, 2, 7, 3, 7, 5, 1, 0} 158 | 159 | sort_quick(arr) = {0, 1, 2, 2, 3, 3, 5, 6, 7, 7} 160 | arr = {2, 6, 3, 2, 7, 3, 7, 5, 1, 0} 161 | 162 | sort_quick_inplace(arr) 163 | arr = {0, 1, 2, 2, 3, 3, 5, 6, 7, 7} 164 | ``` 165 | -------------------------------------------------------------------------------- /std/bits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * bits.cpp 3 | * 4 | * Created on: Jun 20, 2015 5 | * Author: nbingham 6 | */ 7 | 8 | #include 9 | 10 | namespace core 11 | { 12 | 13 | bits::bits() 14 | { 15 | 16 | } 17 | 18 | bits::~bits() 19 | { 20 | 21 | } 22 | 23 | bits &operator<<(bits &str, char v) 24 | { 25 | str.push_back((unsigned char)v); 26 | return str; 27 | } 28 | 29 | bits &operator<<(bits &str, unsigned char v) 30 | { 31 | str.push_back(v); 32 | return str; 33 | } 34 | 35 | bits &operator<<(bits &str, short v) 36 | { 37 | str.reserve(str.size() + sizeof(short)); 38 | memcpy(str.data + str.size(), &v, sizeof(short)); 39 | str.alloc_back(sizeof(short)); 40 | return str; 41 | } 42 | 43 | bits &operator<<(bits &str, unsigned short v) 44 | { 45 | str.reserve(str.size() + sizeof(unsigned short)); 46 | memcpy(str.data + str.size(), &v, sizeof(unsigned short)); 47 | str.alloc_back(sizeof(unsigned short)); 48 | return str; 49 | } 50 | 51 | bits &operator<<(bits &str, int v) 52 | { 53 | str.reserve(str.size() + sizeof(int)); 54 | memcpy(str.data + str.size(), &v, sizeof(int)); 55 | str.alloc_back(sizeof(int)); 56 | return str; 57 | } 58 | 59 | bits &operator<<(bits &str, unsigned int v) 60 | { 61 | str.reserve(str.size() + sizeof(unsigned int)); 62 | memcpy(str.data + str.size(), &v, sizeof(unsigned int)); 63 | str.alloc_back(sizeof(unsigned int)); 64 | return str; 65 | } 66 | 67 | bits &operator<<(bits &str, long v) 68 | { 69 | str.reserve(str.size() + sizeof(long)); 70 | memcpy(str.data + str.size(), &v, sizeof(long)); 71 | str.alloc_back(sizeof(long)); 72 | return str; 73 | } 74 | 75 | bits &operator<<(bits &str, unsigned long v) 76 | { 77 | str.reserve(str.size() + sizeof(unsigned long)); 78 | memcpy(str.data + str.size(), &v, sizeof(unsigned long)); 79 | str.alloc_back(sizeof(unsigned long)); 80 | return str; 81 | } 82 | 83 | bits &operator<<(bits &str, long long v) 84 | { 85 | str.reserve(str.size() + sizeof(long long)); 86 | memcpy(str.data + str.size(), &v, sizeof(long long)); 87 | str.alloc_back(sizeof(long long)); 88 | return str; 89 | } 90 | 91 | bits &operator<<(bits &str, unsigned long long v) 92 | { 93 | str.reserve(str.size() + sizeof(unsigned long long)); 94 | memcpy(str.data + str.size(), &v, sizeof(unsigned long long)); 95 | str.alloc_back(sizeof(unsigned long long)); 96 | return str; 97 | } 98 | 99 | bits &operator<<(bits &str, bool v) 100 | { 101 | str.reserve(str.size() + sizeof(bool)); 102 | memcpy(str.data + str.size(), &v, sizeof(bool)); 103 | str.alloc_back(sizeof(bool)); 104 | return str; 105 | } 106 | 107 | bits &operator<<(bits &str, float v) 108 | { 109 | str.reserve(str.size() + sizeof(float)); 110 | memcpy(str.data + str.size(), &v, sizeof(float)); 111 | str.alloc_back(sizeof(float)); 112 | return str; 113 | } 114 | 115 | bits &operator<<(bits &str, double v) 116 | { 117 | str.reserve(str.size() + sizeof(double)); 118 | memcpy(str.data + str.size(), &v, sizeof(double)); 119 | str.alloc_back(sizeof(double)); 120 | return str; 121 | } 122 | 123 | bits &operator<<(bits &str, const char *v) 124 | { 125 | int n = strlen(v); 126 | str.reserve(str.size() + n); 127 | memcpy(str.data + str.size(), v, n); 128 | str.alloc_back(n); 129 | return str; 130 | } 131 | 132 | bits &operator<<(bits &str, char *v) 133 | { 134 | int n = strlen(v); 135 | str.reserve(str.size() + n); 136 | memcpy(str.data + str.size(), v, n); 137 | str.alloc_back(n); 138 | return str; 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /std/bits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bits.h 3 | * 4 | * Created on: Jun 20, 2015 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace core 15 | { 16 | 17 | struct bits : array 18 | { 19 | bits(); 20 | ~bits(); 21 | 22 | using typename array::type; 23 | using typename array::iterator; 24 | using typename array::const_iterator; 25 | 26 | using array::begin; 27 | using array::end; 28 | using array::rbegin; 29 | using array::rend; 30 | using array::sub; 31 | using array::size; 32 | 33 | using array::operator=; 34 | }; 35 | 36 | bits &operator<<(bits &str, char v); 37 | bits &operator<<(bits &str, short v); 38 | bits &operator<<(bits &str, int v); 39 | bits &operator<<(bits &str, long v); 40 | bits &operator<<(bits &str, long long v); 41 | bits &operator<<(bits &str, unsigned char v); 42 | bits &operator<<(bits &str, unsigned short v); 43 | bits &operator<<(bits &str, unsigned int v); 44 | bits &operator<<(bits &str, unsigned long v); 45 | bits &operator<<(bits &str, unsigned long long v); 46 | bits &operator<<(bits &str, bool v); 47 | bits &operator<<(bits &str, float v); 48 | bits &operator<<(bits &str, double v); 49 | bits &operator<<(bits &str, const char *v); 50 | bits &operator<<(bits &str, char *v); 51 | 52 | template 53 | bits &operator<<(bits &str, const container &v) 54 | { 55 | for (typename container::const_iterator i = v.begin(); i != v.end(); i++) 56 | str << *i; 57 | return str; 58 | } 59 | 60 | template 61 | bits &operator<<(bits &str, const pair &v) 62 | { 63 | str << v.first << v.second; 64 | return str; 65 | } 66 | 67 | template 68 | bits &operator<<(bits &str, const implier &v) 69 | { 70 | str << v.key << v.value; 71 | return str; 72 | } 73 | 74 | template 75 | bits &hash_data(bits &str, T value) 76 | { 77 | str << value; 78 | return str; 79 | } 80 | 81 | template 82 | bits &hash_data(bits &str, const implier &value) 83 | { 84 | str << value.key; 85 | return str; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /std/boundary.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef NULL 6 | #define NULL 0 7 | #endif 8 | 9 | namespace core 10 | { 11 | 12 | template 13 | struct boundary; 14 | 15 | template 16 | struct boundary_const_iterator 17 | { 18 | friend class boundary; 19 | 20 | protected: 21 | const boundary *root; 22 | value_type value; 23 | 24 | boundary_const_iterator(const boundary *root, value_type value) 25 | { 26 | this->root = root; 27 | this->value = value; 28 | } 29 | public: 30 | typedef value_type type; 31 | 32 | boundary_const_iterator() 33 | { 34 | this->root = NULL; 35 | } 36 | 37 | ~boundary_const_iterator() 38 | { 39 | 40 | } 41 | 42 | operator bool() const 43 | { 44 | return root != NULL && value != root->start-1 && value != root->finish; 45 | } 46 | 47 | value_type operator*() const 48 | { 49 | return value; 50 | } 51 | 52 | const value_type *operator->() const 53 | { 54 | return &value; 55 | } 56 | 57 | const value_type *ptr() const 58 | { 59 | return &value; 60 | } 61 | 62 | value_type get() const 63 | { 64 | return value; 65 | } 66 | 67 | int idx() const 68 | { 69 | return value - root->start; 70 | } 71 | 72 | boundary_const_iterator operator++(int) 73 | { 74 | boundary_const_iterator result = *this; 75 | value++; 76 | return result; 77 | } 78 | 79 | boundary_const_iterator operator--(int) 80 | { 81 | boundary_const_iterator result = *this; 82 | value--; 83 | return result; 84 | } 85 | 86 | boundary_const_iterator &operator++() 87 | { 88 | value++; 89 | return *this; 90 | } 91 | 92 | boundary_const_iterator &operator--() 93 | { 94 | value--; 95 | return *this; 96 | } 97 | 98 | boundary_const_iterator &operator+=(int n) 99 | { 100 | value += n; 101 | return *this; 102 | } 103 | 104 | boundary_const_iterator &operator-=(int n) 105 | { 106 | value -= n; 107 | return *this; 108 | } 109 | 110 | boundary_const_iterator operator+(int n) const 111 | { 112 | boundary_const_iterator result; 113 | result.root = root; 114 | result.value = value + n; 115 | return result; 116 | } 117 | 118 | boundary_const_iterator operator-(int n) const 119 | { 120 | boundary_const_iterator result; 121 | result.root = root; 122 | result.value = value - n; 123 | return result; 124 | } 125 | 126 | bool operator==(boundary_const_iterator i) const 127 | { 128 | return value == i.value; 129 | } 130 | 131 | bool operator!=(boundary_const_iterator i) const 132 | { 133 | return value != i.value; 134 | } 135 | 136 | int operator-(boundary_const_iterator i) const 137 | { 138 | return value - i.value; 139 | } 140 | 141 | boundary sub(int length) const 142 | { 143 | value_type bound = value+length; 144 | if (length < 0) 145 | return boundary(bound < root->start ? root->start : bound, value); 146 | else 147 | return boundary(value, bound > root->finish ? root->finish : bound); 148 | } 149 | 150 | boundary subcpy(int length) const 151 | { 152 | value_type bound = value+length; 153 | if (length < 0) 154 | return boundary(bound < root->start ? root->start : bound, value); 155 | else 156 | return boundary(value, bound > root->finish ? root->finish : bound); 157 | } 158 | 159 | boundary sub() const 160 | { 161 | return boundary(value, root->finish); 162 | } 163 | 164 | boundary subcpy() const 165 | { 166 | return boundary(value, root->finish); 167 | } 168 | }; 169 | 170 | template 171 | struct boundary : container, boundary_const_iterator > 172 | { 173 | typedef container, boundary_const_iterator > super; 174 | 175 | using typename super::type; 176 | using typename super::iterator; 177 | using typename super::const_iterator; 178 | 179 | value_type start; 180 | value_type finish; 181 | 182 | boundary() 183 | { 184 | } 185 | 186 | boundary(value_type start, value_type finish) 187 | { 188 | this->start = start; 189 | this->finish = finish; 190 | } 191 | 192 | template 193 | boundary(const boundary &a) 194 | { 195 | this->start = a.start; 196 | this->finish = a.finish; 197 | } 198 | 199 | boundary(const_iterator start, const_iterator finish) 200 | { 201 | this->start = *start; 202 | this->finish = *finish; 203 | } 204 | 205 | virtual ~boundary() 206 | { 207 | 208 | } 209 | 210 | // Utility 211 | 212 | int size() const 213 | { 214 | return finish - start; 215 | } 216 | 217 | // Iterators 218 | 219 | const_iterator begin() const 220 | { 221 | return const_iterator(this, start); 222 | } 223 | 224 | const_iterator end() const 225 | { 226 | return const_iterator(this, finish); 227 | } 228 | 229 | const_iterator rbegin() const 230 | { 231 | return const_iterator(this, finish-1); 232 | } 233 | 234 | const_iterator rend() const 235 | { 236 | return const_iterator(this, start-1); 237 | } 238 | 239 | const_iterator at(int i) const 240 | { 241 | if (i < 0) 242 | i += size(); 243 | 244 | return const_iterator(this, start + i); 245 | } 246 | 247 | // Accessors 248 | 249 | value_type front() const 250 | { 251 | return start; 252 | } 253 | 254 | value_type back() const 255 | { 256 | return finish-1; 257 | } 258 | 259 | value_type get(int i) const 260 | { 261 | if (i < 0) 262 | i += size(); 263 | return start + i; 264 | } 265 | 266 | value_type operator[](int i) const 267 | { 268 | if (i < 0) 269 | i += size(); 270 | return start + i; 271 | } 272 | 273 | // Slicing 274 | boundary sub(int start, int end) const 275 | { 276 | int count = size(); 277 | start = start < 0 ? count + start : start; 278 | end = end < 0 ? count + end : end; 279 | return boundary(this->start + start, this->start + end); 280 | } 281 | 282 | boundary sub(int start) const 283 | { 284 | int count = size(); 285 | start = start < 0 ? count + start : start; 286 | return boundary(this->start + start, this->finish); 287 | } 288 | 289 | boundary sub() const 290 | { 291 | return boundary(start, finish); 292 | } 293 | 294 | boundary subcpy(int start, int end) const 295 | { 296 | int count = size(); 297 | start = start < 0 ? count + start : start; 298 | end = end < 0 ? count + end : end; 299 | return boundary(this->start + start, this->start + end); 300 | } 301 | 302 | boundary subcpy(int start) const 303 | { 304 | int count = size(); 305 | start = start < 0 ? count + start : start; 306 | return boundary(this->start + start, this->finish); 307 | } 308 | 309 | boundary subcpy() const 310 | { 311 | return boundary(start, finish); 312 | } 313 | 314 | template 315 | boundary sample(container &c) const 316 | { 317 | return boundary(c.at(start), c.at(finish)); 318 | } 319 | 320 | template 321 | boundary sample(const container &c) const 322 | { 323 | return boundary(c.at(start), c.at(finish)); 324 | } 325 | 326 | boundary idx() const 327 | { 328 | return boundary(start.idx(), finish.idx()); 329 | } 330 | 331 | // Modifiers 332 | 333 | void swap(boundary &root) 334 | { 335 | value_type tmp_start = start; 336 | value_type tmp_finish = finish; 337 | start = root.start; 338 | finish = root.finish; 339 | root.start = tmp_start; 340 | root.finish = tmp_finish; 341 | } 342 | 343 | boundary &operator=(const boundary &root) 344 | { 345 | start = root.start; 346 | finish = root.finish; 347 | return *this; 348 | } 349 | }; 350 | 351 | // Faster comparison algorithms 352 | 353 | template 354 | bool operator==(boundary s1, boundary s2) 355 | { 356 | return (s1.start == s2.start && s1.finish == s2.finish); 357 | } 358 | 359 | template 360 | bool operator!=(boundary s1, boundary s2) 361 | { 362 | return (s1.start != s2.start || s1.finish != s2.finish); 363 | } 364 | 365 | template 366 | bool operator<(boundary s1, boundary s2) 367 | { 368 | return (s1.start < s2.start || (s1.start == s2.start && 369 | s1.finish < s2.finish)); 370 | } 371 | 372 | template 373 | bool operator>(boundary s1, boundary s2) 374 | { 375 | return (s1.start > s2.start || (s1.start == s2.start && 376 | s1.finish > s2.finish)); 377 | } 378 | 379 | template 380 | bool operator<=(boundary s1, boundary s2) 381 | { 382 | return (s1.start < s2.start || (s1.start == s2.start && 383 | s1.finish <= s2.finish)); 384 | } 385 | 386 | template 387 | bool operator>=(boundary s1, boundary s2) 388 | { 389 | return (s1.start > s2.start || (s1.start == s2.start && 390 | s1.finish >= s2.finish)); 391 | } 392 | 393 | // Constructers that auto-determine value_type 394 | template 395 | boundary boundary_t(value_type start, value_type finish) 396 | { 397 | return boundary(start, finish); 398 | } 399 | 400 | } 401 | 402 | -------------------------------------------------------------------------------- /std/container.h: -------------------------------------------------------------------------------- 1 | /* 2 | * slice.h 3 | * 4 | * Created on: Oct 13, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace core 11 | { 12 | 13 | template 14 | struct container 15 | { 16 | typedef value_type type; 17 | typedef container_iterator iterator; 18 | typedef container_const_iterator const_iterator; 19 | 20 | container() {} 21 | virtual ~container() {}; 22 | 23 | virtual const_iterator begin() const = 0; 24 | virtual const_iterator end() const = 0; 25 | virtual const_iterator rbegin() const = 0; 26 | virtual const_iterator rend() const = 0; 27 | }; 28 | 29 | template 30 | bool compare(const container &a, const container &b) 31 | { 32 | ci0 i = a.begin(); 33 | ci1 j = b.begin(); 34 | for (; i && j; i++, j++) 35 | { 36 | if (*i < *j) 37 | return -1; 38 | else if (*j < *i) 39 | return 1; 40 | } 41 | if (j) 42 | return -1; 43 | else if (i) 44 | return 1; 45 | else 46 | return 0; 47 | } 48 | 49 | template 50 | bool operator==(const container &a, const container &b) 51 | { 52 | ci0 i = a.begin(); 53 | ci1 j = b.begin(); 54 | for (; i && j; i++, j++) 55 | if (!(*i == *j)) 56 | return false; 57 | 58 | return !(i || j); 59 | } 60 | 61 | template 62 | bool operator!=(const container &a, const container &b) 63 | { 64 | return !(a == b); 65 | } 66 | 67 | template 68 | bool operator<(const container &a, const container &b) 69 | { 70 | ci0 i = a.begin(); 71 | ci1 j = b.begin(); 72 | for (; i && j; i++, j++) 73 | { 74 | if (*i < *j) 75 | return true; 76 | else if (!(*i == *j)) 77 | return false; 78 | } 79 | 80 | return j; 81 | } 82 | 83 | template 84 | bool operator>(const container &a, const container &b) 85 | { 86 | ci0 i = a.begin(); 87 | ci1 j = b.begin(); 88 | for (; i && j; i++, j++) 89 | { 90 | if (*i > *j) 91 | return true; 92 | else if (!(*i == *j)) 93 | return false; 94 | } 95 | 96 | return i; 97 | } 98 | 99 | template 100 | bool operator<=(const container &a, const container &b) 101 | { 102 | return !(a > b); 103 | } 104 | 105 | template 106 | bool operator>=(const container &a, const container &b) 107 | { 108 | return !(a < b); 109 | } 110 | 111 | } 112 | 113 | -------------------------------------------------------------------------------- /std/file.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * file.cpp 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace core 15 | { 16 | 17 | file::file() 18 | { 19 | desc = -1; 20 | } 21 | 22 | file::file(int desc) 23 | { 24 | this->desc = desc; 25 | index = -1; 26 | } 27 | 28 | file::file(const file ©) 29 | { 30 | desc = ::dup(copy.desc); 31 | index = copy.index; 32 | } 33 | 34 | file::file(const char *filename, unsigned char mode, unsigned char owner, unsigned char group, unsigned char user) 35 | { 36 | desc = -1; 37 | open(filename, mode, owner, group, user); 38 | } 39 | 40 | file::file(array filename, unsigned char mode, unsigned char owner, unsigned char group, unsigned char user) 41 | { 42 | desc = -1; 43 | open(filename, mode, owner, group, user); 44 | } 45 | 46 | file::~file() 47 | { 48 | close(); 49 | } 50 | 51 | file::operator bool() const 52 | { 53 | return desc >= 0; 54 | } 55 | 56 | bool file::open(const char *filename, unsigned char mode, unsigned char owner, unsigned char group, unsigned char user) 57 | { 58 | if (desc >= 3) 59 | return false; 60 | 61 | int oflags = O_CREAT; 62 | int rights = 0; 63 | index = 0; 64 | 65 | if ((mode & rw) == rw) 66 | oflags |= O_RDWR; 67 | else if (mode & r) 68 | oflags |= O_RDONLY; 69 | else if (mode & w) 70 | oflags |= O_WRONLY; 71 | 72 | if (mode & replace) 73 | oflags |= O_TRUNC; 74 | 75 | if (mode & exists) 76 | oflags &= ~O_CREAT; 77 | else if (mode & not_exists) 78 | oflags |= O_EXCL; 79 | 80 | if (owner & r) 81 | rights |= S_IRUSR; 82 | if (owner & w) 83 | rights |= S_IWUSR; 84 | if (owner & x) 85 | rights |= S_IXUSR; 86 | 87 | if (group & r) 88 | rights |= S_IRGRP; 89 | if (group & w) 90 | rights |= S_IWGRP; 91 | if (group & x) 92 | rights |= S_IXGRP; 93 | 94 | if (user & r) 95 | rights |= S_IROTH; 96 | if (user & w) 97 | rights |= S_IWOTH; 98 | if (user & x) 99 | rights |= S_IXOTH; 100 | 101 | desc = ::open(filename, oflags, rights); 102 | return desc >= 3; 103 | } 104 | 105 | bool file::open(array filename, unsigned char mode, unsigned char owner, unsigned char group, unsigned char user) 106 | { 107 | if (filename[-1] != '\0') 108 | filename.push_back('\0'); 109 | return open(filename.data, mode, owner, group, user); 110 | } 111 | 112 | bool file::close() 113 | { 114 | if (desc >= 3) 115 | return ::close(desc) == 0; 116 | else 117 | return true; 118 | } 119 | 120 | intptr_t file::size() 121 | { 122 | intptr_t result = ::lseek(desc, 0, SEEK_END); 123 | ::lseek(desc, index, SEEK_SET); 124 | return result; 125 | } 126 | 127 | intptr_t file::set(intptr_t offset) 128 | { 129 | if (offset >= 0) 130 | index = ::lseek(desc, offset, SEEK_SET); 131 | else 132 | index = ::lseek(desc, offset, SEEK_END); 133 | return index; 134 | } 135 | 136 | intptr_t file::mov(intptr_t offset) 137 | { 138 | index = ::lseek(desc, offset, SEEK_CUR); 139 | return index; 140 | } 141 | 142 | intptr_t file::read(intptr_t length, char *str) 143 | { 144 | intptr_t result = ::read(desc, str, length); 145 | index += result; 146 | return result; 147 | } 148 | 149 | intptr_t file::read(intptr_t length, array &str) 150 | { 151 | str.reserve(length); 152 | str.count = ::read(desc, str.data, length); 153 | index += str.count; 154 | return str.count; 155 | } 156 | 157 | array file::read(intptr_t length) 158 | { 159 | array result; 160 | result.reserve(length); 161 | result.count = ::read(desc, result.data, length); 162 | index += result.count; 163 | return result; 164 | } 165 | 166 | intptr_t file::write(intptr_t length, const char *str) 167 | { 168 | intptr_t result = ::write(desc, str, length); 169 | index += result; 170 | return result; 171 | } 172 | 173 | intptr_t file::write(const array &str) 174 | { 175 | intptr_t result = ::write(desc, str.data, str.count); 176 | index += result; 177 | return result; 178 | } 179 | 180 | intptr_t file::read_to(const char *delimiters, array &str) 181 | { 182 | const char *cptr; 183 | do { 184 | char c; 185 | intptr_t count = ::read(desc, &c, 1); 186 | if (count == 0) { 187 | return str.count; 188 | } 189 | str.push_back(c); 190 | for (cptr = delimiters; *cptr and c != *cptr; ++cptr); 191 | } while (not *cptr); 192 | return str.count; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /std/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * file.h 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | namespace core 14 | { 15 | 16 | struct file 17 | { 18 | file(); 19 | file(int desc); 20 | file(const file ©); 21 | file(const char *filename, unsigned char mode = rw, unsigned char owner = rw, unsigned char group = r, unsigned char user = r); 22 | file(array filename, unsigned char mode = rw, unsigned char owner = rw, unsigned char group = r, unsigned char user = r); 23 | ~file(); 24 | 25 | enum { 26 | r = 0x01, // read 27 | w = 0x02, // write 28 | x = 0x04, // execute 29 | rw = 0x03, 30 | rx = 0x05, 31 | wx = 0x06, 32 | rwx = 0x07, 33 | replace = 0x8, // replace with empty file 34 | exists = 0x10, // fail if file doesn't exist 35 | not_exists = 0x20 // fail if file exists 36 | }; 37 | 38 | int desc; 39 | intptr_t index; 40 | 41 | operator bool() const; 42 | 43 | bool open(const char *filename, unsigned char mode = rw, unsigned char owner = rw, unsigned char group = r, unsigned char user = r); 44 | bool open(array, unsigned char mode = rw, unsigned char owner = rw, unsigned char group = r, unsigned char user = r); 45 | bool close(); 46 | 47 | intptr_t size(); 48 | 49 | intptr_t set(intptr_t offset); 50 | intptr_t mov(intptr_t offset); 51 | 52 | intptr_t read(intptr_t length, char *str); 53 | intptr_t read(intptr_t length, array &str); 54 | array read(intptr_t length); 55 | 56 | intptr_t write(intptr_t length, const char *str); 57 | intptr_t write(const array &str); 58 | 59 | intptr_t read_to(const char *delimiters, array &str); 60 | }; 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /std/fill.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fill.h 3 | * 4 | * Created on: May 29, 2016 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace core 13 | { 14 | 15 | template 16 | struct fill; 17 | 18 | template 19 | struct fill_const_iterator 20 | { 21 | protected: 22 | friend class fill; 23 | 24 | const fill *root; 25 | int index; 26 | 27 | fill_const_iterator(const fill *root, int index) 28 | { 29 | this->root = root; 30 | this->index = index; 31 | } 32 | public: 33 | typedef value_type type; 34 | 35 | fill_const_iterator() 36 | { 37 | this->root = NULL; 38 | this->index = 0; 39 | } 40 | 41 | ~fill_const_iterator() 42 | { 43 | 44 | } 45 | 46 | operator bool() const 47 | { 48 | return root != NULL && index >= 0 && index < root->count; 49 | } 50 | 51 | value_type operator*() 52 | { 53 | return root->value; 54 | } 55 | 56 | const value_type *operator->() const 57 | { 58 | return &root->value; 59 | } 60 | 61 | const value_type *ptr() const 62 | { 63 | return &root->value; 64 | } 65 | 66 | value_type get() 67 | { 68 | return root->value; 69 | } 70 | 71 | fill_const_iterator &ref() 72 | { 73 | return *this; 74 | } 75 | 76 | const fill_const_iterator &ref() const 77 | { 78 | return *this; 79 | } 80 | 81 | int idx() const 82 | { 83 | return index; 84 | } 85 | 86 | fill_const_iterator operator++(int) 87 | { 88 | fill_const_iterator result = *this; 89 | index++; 90 | return result; 91 | } 92 | 93 | fill_const_iterator operator--(int) 94 | { 95 | fill_const_iterator result = *this; 96 | index--; 97 | return result; 98 | } 99 | 100 | fill_const_iterator &operator++() 101 | { 102 | index++; 103 | return *this; 104 | } 105 | 106 | fill_const_iterator &operator--() 107 | { 108 | index--; 109 | return *this; 110 | } 111 | 112 | fill_const_iterator &operator+=(int n) 113 | { 114 | index += n; 115 | return *this; 116 | } 117 | 118 | fill_const_iterator &operator-=(int n) 119 | { 120 | index -= n; 121 | return *this; 122 | } 123 | 124 | fill_const_iterator operator+(int n) const 125 | { 126 | fill_const_iterator result; 127 | result.root = root; 128 | result.index = index + n; 129 | return result; 130 | } 131 | 132 | fill_const_iterator operator-(int n) const 133 | { 134 | fill_const_iterator result; 135 | result.root = root; 136 | result.index = index - n; 137 | return result; 138 | } 139 | 140 | bool operator==(fill_const_iterator i) const 141 | { 142 | return index == i.index; 143 | } 144 | 145 | bool operator!=(fill_const_iterator i) const 146 | { 147 | return index != i.index; 148 | } 149 | 150 | int operator-(fill_const_iterator i) const 151 | { 152 | return index - i.index; 153 | } 154 | 155 | fill sub(int length) const 156 | { 157 | if (length < 0) 158 | return fill(-length < index ? -length : index, root->value); 159 | else 160 | return fill(length < root->count - index ? length : root->count - index, root->value); 161 | } 162 | 163 | fill subcpy(int length) const 164 | { 165 | if (length < 0) 166 | return fill(-length < index ? -length : index, root->value); 167 | else 168 | return fill(length < root->count - index ? length : root->count - index, root->value); 169 | } 170 | 171 | fill sub() const 172 | { 173 | return fill(root->count - index, root->value); 174 | } 175 | 176 | fill subcpy() const 177 | { 178 | return fill(root->count - index, root->value); 179 | } 180 | }; 181 | 182 | template 183 | struct fill : container, fill_const_iterator > 184 | { 185 | friend class fill_const_iterator; 186 | 187 | typedef container, fill_const_iterator > super; 188 | using typename super::iterator; 189 | using typename super::const_iterator; 190 | using typename super::type; 191 | 192 | int count; 193 | value_type value; 194 | 195 | fill(int count, value_type value) 196 | { 197 | this->count = count; 198 | this->value = value; 199 | } 200 | 201 | fill(const_iterator left, const_iterator right) 202 | { 203 | this->count = right - left; 204 | this->value = left.root->value; 205 | } 206 | 207 | virtual ~fill() 208 | { 209 | 210 | } 211 | 212 | // Utility 213 | 214 | int size() const 215 | { 216 | return count; 217 | } 218 | 219 | // Iterators 220 | 221 | const_iterator begin() const 222 | { 223 | return const_iterator(this, 0); 224 | } 225 | 226 | const_iterator end() const 227 | { 228 | return const_iterator(this, count); 229 | } 230 | 231 | const_iterator rbegin() const 232 | { 233 | return const_iterator(this, count-1); 234 | } 235 | 236 | const_iterator rend() const 237 | { 238 | return const_iterator(this, -1); 239 | } 240 | 241 | const_iterator at(int i) const 242 | { 243 | if (i < 0) 244 | i += size(); 245 | 246 | return const_iterator(this, i); 247 | } 248 | 249 | // Accessors 250 | 251 | value_type front() const 252 | { 253 | return value; 254 | } 255 | 256 | value_type back() const 257 | { 258 | return value; 259 | } 260 | 261 | value_type get(int i) const 262 | { 263 | return value; 264 | } 265 | 266 | value_type operator[](int i) const 267 | { 268 | return value; 269 | } 270 | 271 | // Slicing 272 | fill sub(int start, int end) const 273 | { 274 | start = start < 0 ? count + start : start; 275 | end = end < 0 ? count + end : end; 276 | return fill(end-start, value); 277 | } 278 | 279 | fill sub(int start) const 280 | { 281 | start = start < 0 ? count + start : start; 282 | return fill(count-start, value); 283 | } 284 | 285 | fill sub() const 286 | { 287 | return fill(count, value); 288 | } 289 | 290 | fill subcpy(int start, int end) const 291 | { 292 | start = start < 0 ? count + start : start; 293 | end = end < 0 ? count + end : end; 294 | return fill(end-start, value); 295 | } 296 | 297 | fill subcpy(int start) const 298 | { 299 | start = start < 0 ? count + start : start; 300 | return fill(count-start, value); 301 | } 302 | 303 | fill subcpy() const 304 | { 305 | return fill(count, value); 306 | } 307 | 308 | template 309 | fill sample(container &c) 310 | { 311 | return fill(count, c.at(value)); 312 | } 313 | 314 | template 315 | fill sample(const container &c) 316 | { 317 | return fill(count, c.at(value)); 318 | } 319 | 320 | fill idx() 321 | { 322 | return fill(count, value.idx()); 323 | } 324 | 325 | // Modifiers 326 | 327 | void swap(fill &root) 328 | { 329 | int tmp_count = count; 330 | value_type tmp_value = value; 331 | count = root.count; 332 | value = root.value; 333 | root.count = tmp_count; 334 | root.value = tmp_value; 335 | } 336 | 337 | fill &operator=(const fill &root) 338 | { 339 | count = root.count; 340 | value = root.value; 341 | return *this; 342 | } 343 | }; 344 | 345 | template 346 | bool operator==(fill s1, fill s2) 347 | { 348 | return (s1.count == s2.count && s1.value == s2.value); 349 | } 350 | 351 | template 352 | bool operator!=(fill s1, fill s2) 353 | { 354 | return (s1.count != s2.count || s1.value != s2.value); 355 | } 356 | 357 | template 358 | bool operator<(fill s1, fill s2) 359 | { 360 | return (s1.value < s2.value || (s1.value == s2.value && 361 | (s1.count < s2.count))); 362 | } 363 | 364 | template 365 | bool operator>(fill s1, fill s2) 366 | { 367 | return (s1.value > s2.value || (s1.value == s2.value && 368 | (s1.count > s2.count))); 369 | } 370 | 371 | template 372 | bool operator<=(fill s1, fill s2) 373 | { 374 | return (s1.value < s2.value || (s1.value == s2.value && 375 | (s1.count <= s2.count))); 376 | } 377 | 378 | template 379 | bool operator>=(fill s1, fill s2) 380 | { 381 | return (s1.value > s2.value || (s1.value == s2.value && 382 | (s1.count >= s2.count))); 383 | } 384 | 385 | template 386 | fill fill_t(int count, value_type value) 387 | { 388 | return fill(count, value); 389 | } 390 | 391 | } 392 | -------------------------------------------------------------------------------- /std/filter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * filter.h 3 | * 4 | * Created on: Oct 7, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | namespace core 14 | { 15 | 16 | template 17 | array filter(container &c, const element &t) 18 | { 19 | array results; 20 | for (typename container::iterator i = c.begin(); i != c.end(); i++) 21 | if (*i == t) 22 | results.push_back(i); 23 | 24 | return results; 25 | } 26 | 27 | template 28 | array filter(const container &c, const element &t) 29 | { 30 | array results; 31 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 32 | if (*i == t) 33 | results.push_back(i); 34 | 35 | return results; 36 | } 37 | 38 | template 39 | array filter_each(container &c, const container2 &c2) 40 | { 41 | array results; 42 | for (typename container::iterator i = c.begin(); i != c.end(); i++) 43 | if (contains(c2, *i)) 44 | results.push_back(i); 45 | 46 | return results; 47 | } 48 | 49 | template 50 | array filter_each(const container &c, const container2 &c2) 51 | { 52 | array results; 53 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 54 | if (contains(c2, *i)) 55 | results.push_back(i); 56 | 57 | return results; 58 | } 59 | 60 | template 61 | array filter_pattern(container &c, const container2 &t) 62 | { 63 | array result; 64 | for (typename container::iterator i = c.begin(); i != c.end(); i++) 65 | { 66 | bool found = true; 67 | typename container::iterator k = i; 68 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 69 | { 70 | if (k == c.end()) 71 | return result; 72 | else 73 | found = (*k == *j); 74 | } 75 | 76 | if (found) 77 | result.push_back(i); 78 | } 79 | 80 | return result; 81 | } 82 | 83 | template 84 | array filter_pattern(const container &c, const container2 &t) 85 | { 86 | array result; 87 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 88 | { 89 | bool found = true; 90 | typename container::const_iterator k = i; 91 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 92 | { 93 | if (k == c.end()) 94 | return result; 95 | else 96 | found = (*k == *j); 97 | } 98 | 99 | if (found) 100 | result.push_back(i); 101 | } 102 | 103 | return result; 104 | } 105 | 106 | } 107 | 108 | -------------------------------------------------------------------------------- /std/hash_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_map.h 3 | * 4 | * Created on: Jun 20, 2015 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | namespace core 14 | { 15 | 16 | template 17 | struct hash_map : hash_set, hash_func> 18 | { 19 | typedef hash_set, hash_func> super; 20 | using typename super::type; 21 | using typename super::iterator; 22 | using typename super::const_iterator; 23 | using super::size; 24 | using super::begin; 25 | using super::end; 26 | using super::rbegin; 27 | using super::rend; 28 | using super::insert; 29 | using super::contains; 30 | using super::position; 31 | using super::insert_at; 32 | 33 | hash_map() 34 | { 35 | } 36 | 37 | ~hash_map() {} 38 | 39 | iterator insert(key_type key, value_type value = value_type()) 40 | { 41 | return super::insert(implier(key, value)); 42 | } 43 | 44 | iterator insert_duplicate(key_type key, value_type value = value_type()) 45 | { 46 | return super::insert_duplicate(implier(key, value)); 47 | } 48 | 49 | iterator find(key_type key) 50 | { 51 | return super::find(implier(key, value_type())); 52 | } 53 | 54 | const_iterator find(key_type key) const 55 | { 56 | return super::find(implier(key, value_type())); 57 | } 58 | 59 | bool contains(key_type key) const 60 | { 61 | return contains(implier(key, value_type())); 62 | } 63 | 64 | value_type &operator[](key_type key) 65 | { 66 | iterator result = insert(key); 67 | return result->value; 68 | } 69 | 70 | void update(const key_type &key, const value_type &value, value_type (*U)(value_type, value_type)) 71 | { 72 | iterator pos = insert(key); 73 | pos->value = U(pos->value, value); 74 | } 75 | }; 76 | 77 | } 78 | -------------------------------------------------------------------------------- /std/hash_set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace core 4 | { 5 | 6 | /** 7 | * copied from wikipedia 8 | * https://en.wikipedia.org/wiki/MurmurHash 9 | * 10 | * under the creative commons license 11 | * http://creativecommons.org/licenses/by-sa/3.0/ 12 | */ 13 | #define ROT32(x, y) ((x << y) | (x >> (32 - y))) // avoid effort 14 | uint32_t murmur3_32(const char *key, int len, uint32_t seed) { 15 | static const uint32_t c1 = 0xcc9e2d51; 16 | static const uint32_t c2 = 0x1b873593; 17 | static const uint32_t r1 = 15; 18 | static const uint32_t r2 = 13; 19 | static const uint32_t m = 5; 20 | static const uint32_t n = 0xe6546b64; 21 | 22 | uint32_t hash = seed; 23 | 24 | const int nblocks = len / 4; 25 | const uint32_t *blocks = (const uint32_t *) key; 26 | int i; 27 | uint32_t k; 28 | for (i = 0; i < nblocks; i++) { 29 | k = blocks[i]; 30 | k *= c1; 31 | k = ROT32(k, r1); 32 | k *= c2; 33 | 34 | hash ^= k; 35 | hash = ROT32(hash, r2) * m + n; 36 | } 37 | 38 | const uint8_t *tail = (const uint8_t *) (key + nblocks * 4); 39 | uint32_t k1 = 0; 40 | 41 | switch (len & 3) { 42 | case 3: 43 | k1 ^= tail[2] << 16; 44 | case 2: 45 | k1 ^= tail[1] << 8; 46 | case 1: 47 | k1 ^= tail[0]; 48 | 49 | k1 *= c1; 50 | k1 = ROT32(k1, r1); 51 | k1 *= c2; 52 | hash ^= k1; 53 | } 54 | 55 | hash ^= len; 56 | hash ^= (hash >> 16); 57 | hash *= 0x85ebca6b; 58 | hash ^= (hash >> 13); 59 | hash *= 0xc2b2ae35; 60 | hash ^= (hash >> 16); 61 | 62 | return hash; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /std/heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * heap.h 3 | * 4 | * Created on: Nov 5, 2020 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace core 15 | { 16 | 17 | template 18 | void heap_down(iterator_type i) 19 | { 20 | while (i) { 21 | iterator_type left = i + (i.idx() + 1); 22 | iterator_type right = left+1; 23 | iterator_type largest = i; 24 | 25 | if (left and *left > *largest) { 26 | largest = left; 27 | } 28 | if (right and *right > *largest) { 29 | largest = right; 30 | } 31 | 32 | if (largest != i) { 33 | i.swap(largest); 34 | i = largest; 35 | } else { 36 | break; 37 | } 38 | } 39 | } 40 | 41 | template 42 | void heap_up(iterator_type i) 43 | { 44 | while ((i-1)) { 45 | iterator_type n = i - ((i.idx() >> 1)+1); 46 | 47 | if (*i > *n) { 48 | i.swap(n); 49 | i = n; 50 | } else { 51 | break; 52 | } 53 | } 54 | } 55 | 56 | template 57 | void heap_make(container_type &c) 58 | { 59 | for (typename container_type::iterator i = c.begin() + (c.size()>>1); i != c.rend(); i--) { 60 | heap_down(i); 61 | } 62 | } 63 | 64 | template 65 | void heap_push(container_type &c, const typename container_type::type &v) 66 | { 67 | c.push_back(v); 68 | heap_up(c.rbegin()); 69 | } 70 | 71 | template 72 | void heap_replace(container_type &c, const typename container_type::type &v) 73 | { 74 | *c.begin() = v; 75 | heap_down(c.begin()); 76 | } 77 | 78 | template 79 | void heap_drop(container_type &c) 80 | { 81 | *c.begin() = *c.rbegin(); 82 | c.drop_back(); 83 | heap_down(c.begin()); 84 | } 85 | 86 | template 87 | typename container_type::type heap_pop(container_type &c) 88 | { 89 | typename container_type::type result = *c.begin(); 90 | heap_drop(c); 91 | return result; 92 | } 93 | 94 | template 95 | void sort_heap_inplace(container_type &c) 96 | { 97 | heap_make(c); 98 | slice > heap = c.sub(); 99 | 100 | while (heap.begin() != heap.end()) 101 | { 102 | heap.rbegin().swap(heap.begin()); 103 | heap.ref.finish--; 104 | heap_down(heap.begin()); 105 | } 106 | } 107 | 108 | } 109 | 110 | -------------------------------------------------------------------------------- /std/implier.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace core 4 | { 5 | 6 | template 7 | struct implier 8 | { 9 | implier() {} 10 | implier(ktype k, vtype v) 11 | { 12 | key = k; 13 | value = v; 14 | } 15 | ~implier() {} 16 | 17 | ktype key; 18 | vtype value; 19 | }; 20 | 21 | template 22 | bool operator==(implier i0, implier i1) 23 | { 24 | return (i0.key == i1.key); 25 | } 26 | 27 | template 28 | bool operator!=(implier i0, implier i1) 29 | { 30 | return (i0.key != i1.key); 31 | } 32 | 33 | template 34 | bool operator<(implier i0, implier i1) 35 | { 36 | return (i0.key < i1.key); 37 | } 38 | 39 | template 40 | bool operator>(implier i0, implier i1) 41 | { 42 | return (i0.key > i1.key); 43 | } 44 | 45 | template 46 | bool operator<=(implier i0, implier i1) 47 | { 48 | return (i0.key <= i1.key); 49 | } 50 | 51 | template 52 | bool operator>=(implier i0, implier i1) 53 | { 54 | return (i0.key >= i1.key); 55 | } 56 | 57 | 58 | template 59 | bool operator==(implier i0, ktype i1) 60 | { 61 | return (i0.key == i1); 62 | } 63 | 64 | template 65 | bool operator!=(implier i0, ktype i1) 66 | { 67 | return (i0.key != i1); 68 | } 69 | 70 | template 71 | bool operator<(implier i0, ktype i1) 72 | { 73 | return (i0.key < i1); 74 | } 75 | 76 | template 77 | bool operator>(implier i0, ktype i1) 78 | { 79 | return (i0.key > i1); 80 | } 81 | 82 | template 83 | bool operator<=(implier i0, ktype i1) 84 | { 85 | return (i0.key <= i1); 86 | } 87 | 88 | template 89 | bool operator>=(implier i0, ktype i1) 90 | { 91 | return (i0.key >= i1); 92 | } 93 | 94 | 95 | template 96 | bool operator==(ktype i0, implier i1) 97 | { 98 | return (i0 == i1.key); 99 | } 100 | 101 | template 102 | bool operator!=(ktype i0, implier i1) 103 | { 104 | return (i0 != i1.key); 105 | } 106 | 107 | template 108 | bool operator<(ktype i0, implier i1) 109 | { 110 | return (i0 < i1.key); 111 | } 112 | 113 | template 114 | bool operator>(ktype i0, implier i1) 115 | { 116 | return (i0 > i1.key); 117 | } 118 | 119 | template 120 | bool operator<=(ktype i0, implier i1) 121 | { 122 | return (i0 <= i1.key); 123 | } 124 | 125 | template 126 | bool operator>=(ktype i0, implier i1) 127 | { 128 | return (i0 >= i1.key); 129 | } 130 | 131 | } 132 | 133 | -------------------------------------------------------------------------------- /std/io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace core 4 | { 5 | 6 | flush_t flush; 7 | flush_t endl("\n"); 8 | stream cin(0); 9 | stream cout(1); 10 | stream cerr(2); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /std/io.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace core 7 | { 8 | 9 | extern flush_t flush; 10 | extern flush_t endl; 11 | extern stream cin; 12 | extern stream cout; 13 | extern stream cerr; 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /std/map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * map.h 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace core 15 | { 16 | 17 | template 18 | struct map : list > 19 | { 20 | map() 21 | { 22 | 23 | } 24 | 25 | ~map() 26 | { 27 | 28 | } 29 | 30 | using typename list >::type; 31 | using typename list >::iterator; 32 | using typename list >::const_iterator; 33 | using list >::begin; 34 | using list >::end; 35 | using list >::rbegin; 36 | using list >::rend; 37 | using list >::sub; 38 | 39 | iterator insert(implier entry) 40 | { 41 | iterator pos = lower_bound(*this, entry); 42 | pos.push(entry); 43 | return (pos-1); 44 | } 45 | 46 | iterator insert(const ktype &key, const vtype &value) 47 | { 48 | iterator pos = lower_bound(*this, key); 49 | pos.push(implier(key, value)); 50 | return (pos-1); 51 | } 52 | 53 | iterator find(const ktype &key) 54 | { 55 | iterator pos = lower_bound(*this, key); 56 | if (pos != end() && pos->key == key) 57 | return pos; 58 | else 59 | return end(); 60 | } 61 | 62 | iterator at(const ktype &key, const vtype &value = vtype()) 63 | { 64 | iterator pos = lower_bound(*this, key); 65 | if (pos == end() || pos->key != key) { 66 | pos.push(implier(key, value)); 67 | return pos-1; 68 | } else 69 | return pos; 70 | } 71 | 72 | vtype &operator[](ktype key) 73 | { 74 | return at(key)->value; 75 | } 76 | 77 | void update(const ktype &key, const vtype &value, vtype (*U)(vtype, vtype)) 78 | { 79 | iterator pos = lower_bound(*this, key); 80 | if (pos == end() || pos->key != key) { 81 | pos.push(implier(key, value)); 82 | } else { 83 | pos->value = U(pos->value, value); 84 | } 85 | } 86 | }; 87 | 88 | } 89 | 90 | -------------------------------------------------------------------------------- /std/pair.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pair.h 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace core 11 | { 12 | 13 | template 14 | struct pair 15 | { 16 | pair() : first(), second() 17 | { 18 | 19 | } 20 | 21 | pair(type1 f, type2 s) : first(f), second(s) 22 | { 23 | } 24 | 25 | ~pair() 26 | { 27 | 28 | } 29 | 30 | type1 first; 31 | type2 second; 32 | }; 33 | 34 | template 35 | bool operator==(pair p1, pair p2) 36 | { 37 | return p1.first == p2.first && p1.second == p2.second; 38 | } 39 | 40 | template 41 | bool operator!=(pair p1, pair p2) 42 | { 43 | return p1.first != p2.first || p1.second != p2.second; 44 | } 45 | 46 | template 47 | bool operator<(pair p1, pair p2) 48 | { 49 | return p1.first < p2.first || (p1.first == p2.first && p1.second < p2.second); 50 | } 51 | 52 | template 53 | bool operator>(pair p1, pair p2) 54 | { 55 | return p1.first > p2.first || (p1.first == p2.first && p1.second > p2.second); 56 | } 57 | 58 | template 59 | bool operator<=(pair p1, pair p2) 60 | { 61 | return p1.first < p2.first || (p1.first == p2.first && p1.second <= p2.second); 62 | } 63 | 64 | template 65 | bool operator>=(pair p1, pair p2) 66 | { 67 | return p1.first > p2.first || (p1.first == p2.first && p1.second >= p2.second); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /std/partite.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace core 6 | { 7 | 8 | struct partite_base 9 | { 10 | partite_base() 11 | { 12 | part = -1; 13 | } 14 | 15 | ~partite_base() 16 | { 17 | } 18 | 19 | int part; 20 | }; 21 | 22 | template 23 | struct partite_node : partite_base 24 | { 25 | partite_node() 26 | { 27 | part = p; 28 | } 29 | 30 | ~partite_node() 31 | { 32 | } 33 | 34 | value_type value; 35 | }; 36 | 37 | template 38 | struct partite : graph 39 | { 40 | partite() 41 | { 42 | for (int i = 0; i < n+1; i++) 43 | parts[i] = &right; 44 | } 45 | 46 | ~partite() 47 | { 48 | for (iterator i = begin(); i != end(); i++) 49 | { 50 | delete *i; 51 | *i = NULL; 52 | } 53 | } 54 | 55 | end_node *parts[n+1]; 56 | 57 | iterator insert(const partite_base* &value) 58 | { 59 | if (value.part < 0 || value.part >= n) 60 | return end(); 61 | 62 | node *result = new node(value); 63 | result->left = parts[value.part+1]->left; 64 | result->right = parts[value.part+1]; 65 | result->left->right = result; 66 | result->right->left = result; 67 | result->index = parts[value.part+1]->index; 68 | update_index(parts[value.part+1]); 69 | 70 | for (int i = value.part; i >= 0 && parts[i] == parts[value.part+1]; i--) 71 | parts[i] = result; 72 | 73 | return iterator(this, result); 74 | } 75 | 76 | iterator begin(int part) 77 | { 78 | return iterator(this, parts[part]); 79 | } 80 | 81 | iterator end(int part) 82 | { 83 | return iterator(this, parts[part+1]); 84 | } 85 | 86 | iterator rbegin(int part) 87 | { 88 | return iterator(this, parts[part+1]->left); 89 | } 90 | 91 | iterator rend(int part) 92 | { 93 | return iterator(this, parts[part]->left); 94 | } 95 | 96 | const_iterator begin(int part) const 97 | { 98 | return const_iterator(this, parts[part]); 99 | } 100 | 101 | const_iterator end(int part) const 102 | { 103 | return const_iterator(this, parts[part]); 104 | } 105 | 106 | const_iterator rbegin(int part) const 107 | { 108 | return const_iterator(this, parts[part+1]->left); 109 | } 110 | 111 | const_iterator rend(int part) const 112 | { 113 | return const_iterator(this, parts[part]->left); 114 | } 115 | }; 116 | 117 | } 118 | 119 | -------------------------------------------------------------------------------- /std/range.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifndef NULL 6 | #define NULL 0 7 | #endif 8 | 9 | namespace core 10 | { 11 | 12 | template 13 | struct range; 14 | 15 | template 16 | struct range_const_iterator 17 | { 18 | friend class range; 19 | 20 | protected: 21 | const range *root; 22 | value_type value; 23 | 24 | range_const_iterator(const range *root, value_type value) 25 | { 26 | this->root = root; 27 | this->value = value; 28 | } 29 | public: 30 | typedef value_type type; 31 | 32 | range_const_iterator() 33 | { 34 | this->root = NULL; 35 | } 36 | 37 | ~range_const_iterator() 38 | { 39 | 40 | } 41 | 42 | operator bool() const 43 | { 44 | return root != NULL && value >= root->start && value < root->finish; 45 | } 46 | 47 | value_type operator*() const 48 | { 49 | return value; 50 | } 51 | 52 | const value_type *operator->() const 53 | { 54 | return &value; 55 | } 56 | 57 | const value_type *ptr() const 58 | { 59 | return &value; 60 | } 61 | 62 | value_type get() const 63 | { 64 | return value; 65 | } 66 | 67 | int idx() const 68 | { 69 | return value - root->start; 70 | } 71 | 72 | range_const_iterator operator++(int) 73 | { 74 | range_const_iterator result = *this; 75 | value++; 76 | return result; 77 | } 78 | 79 | range_const_iterator operator--(int) 80 | { 81 | range_const_iterator result = *this; 82 | value--; 83 | return result; 84 | } 85 | 86 | range_const_iterator &operator++() 87 | { 88 | value++; 89 | return *this; 90 | } 91 | 92 | range_const_iterator &operator--() 93 | { 94 | value--; 95 | return *this; 96 | } 97 | 98 | range_const_iterator &operator+=(int n) 99 | { 100 | value += n; 101 | return *this; 102 | } 103 | 104 | range_const_iterator &operator-=(int n) 105 | { 106 | value -= n; 107 | return *this; 108 | } 109 | 110 | range_const_iterator operator+(int n) const 111 | { 112 | range_const_iterator result; 113 | result.root = root; 114 | result.value = value + n; 115 | return result; 116 | } 117 | 118 | range_const_iterator operator-(int n) const 119 | { 120 | range_const_iterator result; 121 | result.root = root; 122 | result.value = value - n; 123 | return result; 124 | } 125 | 126 | bool operator==(range_const_iterator i) const 127 | { 128 | return value == i.value; 129 | } 130 | 131 | bool operator!=(range_const_iterator i) const 132 | { 133 | return value != i.value; 134 | } 135 | 136 | int operator-(range_const_iterator i) const 137 | { 138 | return value - i.value; 139 | } 140 | 141 | range sub(int length) const 142 | { 143 | value_type bound = value+length; 144 | if (length < 0) 145 | return range(bound < root->start ? root->start : bound, value); 146 | else 147 | return range(value, bound > root->finish ? root->finish : bound); 148 | } 149 | 150 | range subcpy(int length) const 151 | { 152 | value_type bound = value+length; 153 | if (length < 0) 154 | return range(bound < root->start ? root->start : bound, value); 155 | else 156 | return range(value, bound > root->finish ? root->finish : bound); 157 | } 158 | 159 | range sub() const 160 | { 161 | return range(value, root->finish); 162 | } 163 | 164 | range subcpy() const 165 | { 166 | return range(value, root->finish); 167 | } 168 | }; 169 | 170 | template 171 | struct range : container, range_const_iterator > 172 | { 173 | typedef container, range_const_iterator > super; 174 | 175 | using typename super::type; 176 | using typename super::iterator; 177 | using typename super::const_iterator; 178 | 179 | value_type start; 180 | value_type finish; 181 | 182 | range() 183 | { 184 | } 185 | 186 | range(value_type start, value_type finish) 187 | { 188 | this->start = start; 189 | this->finish = finish; 190 | } 191 | 192 | template 193 | range(const range &a) 194 | { 195 | this->start = a.start; 196 | this->finish = a.finish; 197 | } 198 | 199 | range(const_iterator start, const_iterator finish) 200 | { 201 | this->start = *start; 202 | this->finish = *finish; 203 | } 204 | 205 | virtual ~range() 206 | { 207 | 208 | } 209 | 210 | // Utility 211 | 212 | int size() const 213 | { 214 | return finish - start; 215 | } 216 | 217 | // Iterators 218 | 219 | const_iterator begin() const 220 | { 221 | return const_iterator(this, start); 222 | } 223 | 224 | const_iterator end() const 225 | { 226 | return const_iterator(this, finish); 227 | } 228 | 229 | const_iterator rbegin() const 230 | { 231 | return const_iterator(this, finish-1); 232 | } 233 | 234 | const_iterator rend() const 235 | { 236 | return const_iterator(this, start-1); 237 | } 238 | 239 | const_iterator at(int i) const 240 | { 241 | if (i < 0) 242 | i += size(); 243 | 244 | return const_iterator(this, start + i); 245 | } 246 | 247 | // Accessors 248 | 249 | value_type front() const 250 | { 251 | return start; 252 | } 253 | 254 | value_type back() const 255 | { 256 | return finish-1; 257 | } 258 | 259 | value_type get(int i) const 260 | { 261 | if (i < 0) 262 | i += size(); 263 | return start + i; 264 | } 265 | 266 | value_type operator[](int i) const 267 | { 268 | if (i < 0) 269 | i += size(); 270 | return start + i; 271 | } 272 | 273 | // Slicing 274 | range sub(int start, int end) const 275 | { 276 | int count = size(); 277 | start = start < 0 ? count + start : start; 278 | end = end < 0 ? count + end : end; 279 | return range(this->start + start, this->start + end); 280 | } 281 | 282 | range sub(int start) const 283 | { 284 | int count = size(); 285 | start = start < 0 ? count + start : start; 286 | return range(this->start + start, this->finish); 287 | } 288 | 289 | range sub() const 290 | { 291 | return range(start, finish); 292 | } 293 | 294 | range subcpy(int start, int end) const 295 | { 296 | int count = size(); 297 | start = start < 0 ? count + start : start; 298 | end = end < 0 ? count + end : end; 299 | return range(this->start + start, this->start + end); 300 | } 301 | 302 | range subcpy(int start) const 303 | { 304 | int count = size(); 305 | start = start < 0 ? count + start : start; 306 | return range(this->start + start, this->finish); 307 | } 308 | 309 | range subcpy() const 310 | { 311 | return range(start, finish); 312 | } 313 | 314 | template 315 | range sample(container &c) const 316 | { 317 | return range(c.at(start), c.at(finish)); 318 | } 319 | 320 | template 321 | range sample(const container &c) const 322 | { 323 | return range(c.at(start), c.at(finish)); 324 | } 325 | 326 | range idx() const 327 | { 328 | return range(start.idx(), finish.idx()); 329 | } 330 | 331 | // Modifiers 332 | 333 | void swap(range &root) 334 | { 335 | value_type tmp_start = start; 336 | value_type tmp_finish = finish; 337 | start = root.start; 338 | finish = root.finish; 339 | root.start = tmp_start; 340 | root.finish = tmp_finish; 341 | } 342 | 343 | range &operator=(const range &root) 344 | { 345 | start = root.start; 346 | finish = root.finish; 347 | return *this; 348 | } 349 | }; 350 | 351 | // Faster comparison algorithms 352 | 353 | template 354 | bool operator==(range s1, range s2) 355 | { 356 | return (s1.start == s2.start && s1.finish == s2.finish); 357 | } 358 | 359 | template 360 | bool operator!=(range s1, range s2) 361 | { 362 | return (s1.start != s2.start || s1.finish != s2.finish); 363 | } 364 | 365 | template 366 | bool operator<(range s1, range s2) 367 | { 368 | return (s1.start < s2.start || (s1.start == s2.start && 369 | s1.finish < s2.finish)); 370 | } 371 | 372 | template 373 | bool operator>(range s1, range s2) 374 | { 375 | return (s1.start > s2.start || (s1.start == s2.start && 376 | s1.finish > s2.finish)); 377 | } 378 | 379 | template 380 | bool operator<=(range s1, range s2) 381 | { 382 | return (s1.start < s2.start || (s1.start == s2.start && 383 | s1.finish <= s2.finish)); 384 | } 385 | 386 | template 387 | bool operator>=(range s1, range s2) 388 | { 389 | return (s1.start > s2.start || (s1.start == s2.start && 390 | s1.finish >= s2.finish)); 391 | } 392 | 393 | // Constructers that auto-determine value_type 394 | template 395 | range range_t(value_type start, value_type finish) 396 | { 397 | return range(start, finish); 398 | } 399 | 400 | } 401 | 402 | -------------------------------------------------------------------------------- /std/search.h: -------------------------------------------------------------------------------- 1 | /* 2 | * search.h 3 | * 4 | * Created on: Oct 7, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | namespace core 11 | { 12 | 13 | template 14 | typename container::iterator find_first(container &c, const element &t) 15 | { 16 | for (typename container::iterator i = c.begin(); i != c.end(); i++) 17 | if (*i == t) 18 | return i; 19 | 20 | return c.end(); 21 | } 22 | 23 | template 24 | typename container::const_iterator find_first(const container &c, const element &t) 25 | { 26 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 27 | if (*i == t) 28 | return i; 29 | 30 | return c.end(); 31 | } 32 | 33 | template 34 | bool contains(const container &c, const element &t) 35 | { 36 | return (find_first(c, t) != c.end()); 37 | } 38 | 39 | template 40 | typename container::iterator find_last(container &c, const element &t) 41 | { 42 | for (typename container::iterator i = c.rbegin(); i != c.rend(); i--) 43 | if (*i == t) 44 | return i; 45 | 46 | return c.rend(); 47 | } 48 | 49 | template 50 | typename container::const_iterator find_last(const container &c, const element &t) 51 | { 52 | for (typename container::const_iterator i = c.rbegin(); i != c.rend(); i--) 53 | if (*i == t) 54 | return i; 55 | 56 | return c.rend(); 57 | } 58 | 59 | template 60 | int count_all(const container &c, const element &t) 61 | { 62 | int result = 0; 63 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 64 | result += (*i == t); 65 | return result; 66 | } 67 | 68 | template 69 | typename container1::iterator find_first_of(container1 &c1, const container2 &c2) 70 | { 71 | for (typename container1::iterator i = c1.begin(); i != c1.end(); i++) 72 | if (contains(c2, *i)) 73 | return i; 74 | 75 | return c1.end(); 76 | } 77 | 78 | template 79 | typename container1::const_iterator find_first_of(const container1 &c1, const container2 &c2) 80 | { 81 | for (typename container1::const_iterator i = c1.begin(); i != c1.end(); i++) 82 | if (contains(c2, *i)) 83 | return i; 84 | 85 | return c1.end(); 86 | } 87 | 88 | template 89 | bool contains_one_of(const container1 &c1, const container2 &c2) 90 | { 91 | return (find_first_of(c1, c2) != c1.end()); 92 | } 93 | 94 | template 95 | typename container1::iterator find_last_of(container1 &c1, const container2 &c2) 96 | { 97 | for (typename container1::iterator i = c1.rbegin(); i != c1.rend(); i--) 98 | if (contains(c2, *i)) 99 | return i; 100 | 101 | return c1.rend(); 102 | } 103 | 104 | template 105 | typename container1::const_iterator find_last_of(const container1 &c1, const container2 &c2) 106 | { 107 | for (typename container1::const_iterator i = c1.rbegin(); i != c1.rend(); i--) 108 | if (contains(c2, *i)) 109 | return i; 110 | 111 | return c1.rend(); 112 | } 113 | 114 | template 115 | bool contains_all_of(const container1 &c1, const container2 &c2) 116 | { 117 | for (typename container2::const_iterator i = c2.begin(); i != c2.end(); i++) 118 | if (!contains(c1, *i)) 119 | return false; 120 | 121 | return true; 122 | } 123 | 124 | template 125 | int count_all_of(const container &c, const container2 &c2) 126 | { 127 | int result = 0; 128 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 129 | result += contains(c2, *i); 130 | return result; 131 | } 132 | 133 | template 134 | typename container::iterator find_first_pattern(container &c, const container2 &t) 135 | { 136 | for (typename container::iterator i = c.begin(); i != c.end(); i++) 137 | { 138 | bool found = true; 139 | typename container::iterator k = i; 140 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 141 | { 142 | if (k == c.end()) 143 | return c.end(); 144 | else 145 | found = (*k == *j); 146 | } 147 | 148 | if (found) 149 | return i; 150 | } 151 | 152 | return c.end(); 153 | } 154 | 155 | template 156 | typename container::const_iterator find_first_pattern(const container &c, const container2 &t) 157 | { 158 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 159 | { 160 | bool found = true; 161 | typename container::const_iterator k = i; 162 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 163 | { 164 | if (k == c.end()) 165 | return c.end(); 166 | else 167 | found = (*k == *j); 168 | } 169 | 170 | if (found) 171 | return i; 172 | } 173 | 174 | return c.end(); 175 | } 176 | 177 | template 178 | typename container::iterator find_last_pattern(container &c, const container2 &t) 179 | { 180 | for (typename container::iterator i = c.rbegin(); i != c.rend(); i--) 181 | { 182 | bool found = true; 183 | typename container::iterator k = i; 184 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 185 | found = (k != c.end()) && (*k == *j); 186 | 187 | if (found) 188 | return i; 189 | } 190 | 191 | return c.rend(); 192 | } 193 | 194 | template 195 | typename container::const_iterator find_last_pattern(const container &c, const container2 &t) 196 | { 197 | for (typename container::const_iterator i = c.rbegin(); i != c.rend(); i--) 198 | { 199 | bool found = true; 200 | typename container::const_iterator k = i; 201 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 202 | found = (k != c.end()) && (*k == *j); 203 | 204 | if (found) 205 | return i; 206 | } 207 | 208 | return c.rend(); 209 | } 210 | 211 | template 212 | int count_all_pattern(const container &c, const container2 &t) 213 | { 214 | int result = 0; 215 | for (typename container::const_iterator i = c.begin(); i != c.end(); i++) 216 | { 217 | bool found = true; 218 | typename container::const_iterator k = i; 219 | for (typename container2::const_iterator j = t.begin(); j != t.end() && found; j++,k++) 220 | { 221 | if (k == c.end()) 222 | return result; 223 | else 224 | found = (*k == *j); 225 | } 226 | 227 | result += found; 228 | } 229 | 230 | return result; 231 | } 232 | 233 | template 234 | typename container::iterator lower_bound(container &c, const element &t, int radix = 2) 235 | { 236 | return lower_bound(c.begin(), c.end(), t, radix, c.size()); 237 | } 238 | 239 | template 240 | typename container::const_iterator lower_bound(const container &c, const element &t, int radix = 2) 241 | { 242 | return lower_bound(c.begin(), c.end(), t, radix, c.size()); 243 | } 244 | 245 | template 246 | iterator lower_bound(iterator start, iterator end, const element &t, int radix = 2, int size = -1) 247 | { 248 | if (size < 0) 249 | size = end - start; 250 | 251 | if (size >= radix) 252 | { 253 | int D = radix - size; 254 | for (iterator i = start; i != end; i++) 255 | { 256 | if (D > 0) 257 | { 258 | if (t <= *(i-1)) 259 | return lower_bound(start, i, t, radix, size/radix); 260 | start = i; 261 | D += radix - size; 262 | } 263 | else 264 | D += radix; 265 | } 266 | 267 | return lower_bound(start, end, t, radix, size%radix); 268 | } 269 | else 270 | { 271 | iterator i = start; 272 | while (i != end && *i < t) 273 | i++; 274 | return i; 275 | } 276 | } 277 | 278 | template 279 | typename container::iterator upper_bound(container &c, const element &t, int radix = 2) 280 | { 281 | return upper_bound(c.begin(), c.end(), t, radix, c.size()); 282 | } 283 | 284 | template 285 | typename container::const_iterator upper_bound(const container &c, const element &t, int radix = 2) 286 | { 287 | return upper_bound(c.begin(), c.end(), t, radix, c.size()); 288 | } 289 | 290 | template 291 | iterator upper_bound(iterator start, iterator end, const element &t, int radix = 2, int size = -1) 292 | { 293 | if (size < 0) 294 | size = end - start; 295 | 296 | if (size >= radix) 297 | { 298 | int D = radix - size; 299 | for (iterator i = start; i != end; i++) 300 | { 301 | if (D > 0) 302 | { 303 | if (t < *(i-1)) 304 | return upper_bound(start, i, t, radix, size/radix); 305 | start = i; 306 | D += radix - size; 307 | } 308 | else 309 | D += radix; 310 | } 311 | 312 | return upper_bound(start, end, t, radix, size%radix); 313 | } 314 | else 315 | { 316 | iterator i = start; 317 | while (i != end && *i <= t) 318 | i++; 319 | return i; 320 | } 321 | } 322 | 323 | } 324 | 325 | -------------------------------------------------------------------------------- /std/slice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * slice.h 3 | * 4 | * Created on: Oct 13, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace core 13 | { 14 | 15 | template 16 | struct elem_type 17 | { 18 | typedef typename container_type::type type; 19 | }; 20 | 21 | template 22 | struct elem_type 23 | { 24 | typedef value type; 25 | }; 26 | 27 | template 28 | struct slice; 29 | 30 | template 31 | struct slice_const_iterator; 32 | 33 | template 34 | struct slice_iterator 35 | { 36 | typedef typename container_type::iterator iterator_type; 37 | typedef typename container_type::const_iterator const_iterator_type; 38 | 39 | typedef typename elem_type::type type; 40 | 41 | iterator_type ref; 42 | 43 | slice_iterator() {} 44 | slice_iterator(const iterator_type ©) : ref(copy) {} 45 | ~slice_iterator() {} 46 | 47 | operator bool() const 48 | { 49 | return (bool)ref && (bool)*ref; 50 | } 51 | 52 | operator typename iterator_type::type() const 53 | { 54 | return *ref; 55 | } 56 | 57 | type &operator*() 58 | { 59 | return **ref; 60 | } 61 | 62 | type *operator->() 63 | { 64 | return &(**ref); 65 | } 66 | 67 | type *ptr() 68 | { 69 | return &(**ref); 70 | } 71 | 72 | type &get() 73 | { 74 | return **ref; 75 | } 76 | 77 | int idx() const 78 | { 79 | return ref.idx(); 80 | } 81 | 82 | slice_iterator operator++(int) 83 | { 84 | return ref++; 85 | } 86 | 87 | slice_iterator operator--(int) 88 | { 89 | return ref--; 90 | } 91 | 92 | slice_iterator &operator++() 93 | { 94 | ++ref; 95 | return *this; 96 | } 97 | 98 | slice_iterator &operator--() 99 | { 100 | --ref; 101 | return *this; 102 | } 103 | 104 | slice_iterator &operator+=(int n) 105 | { 106 | ref += n; 107 | return *this; 108 | } 109 | 110 | slice_iterator &operator-=(int n) 111 | { 112 | ref -= n; 113 | return *this; 114 | } 115 | 116 | slice_iterator operator+(int n) const 117 | { 118 | return ref + n; 119 | } 120 | 121 | slice_iterator operator-(int n) const 122 | { 123 | return ref - n; 124 | } 125 | 126 | bool operator==(slice_iterator i) const 127 | { 128 | return ref == i.ref; 129 | } 130 | 131 | bool operator!=(slice_iterator i) const 132 | { 133 | return ref != i.ref; 134 | } 135 | 136 | bool operator==(slice_const_iterator i) const 137 | { 138 | return ref == i.ref; 139 | } 140 | 141 | bool operator!=(slice_const_iterator i) const 142 | { 143 | return ref != i.ref; 144 | } 145 | 146 | int operator-(slice_iterator i) const 147 | { 148 | return ref - i.ref; 149 | } 150 | 151 | int operator-(slice_const_iterator i) const 152 | { 153 | return ref - i.ref; 154 | } 155 | 156 | slice sub(int length) 157 | { 158 | return ref.subcpy(length); 159 | } 160 | 161 | slice subcpy(int length) 162 | { 163 | return ref.subcpy(length); 164 | } 165 | 166 | slice sub() 167 | { 168 | return ref.subcpy(); 169 | } 170 | 171 | slice subcpy() 172 | { 173 | return ref.subcpy(); 174 | } 175 | 176 | void swap(slice_iterator i) 177 | { 178 | ref.get().swap(i.ref.get()); 179 | } 180 | 181 | void swap(slice_const_iterator i) 182 | { 183 | ref.get().swap(i.ref.get()); 184 | } 185 | 186 | slice_iterator &operator=(slice_iterator i) 187 | { 188 | ref = i.ref; 189 | return *this; 190 | } 191 | }; 192 | 193 | template 194 | struct slice_const_iterator 195 | { 196 | typedef typename container_type::iterator iterator_type; 197 | typedef typename container_type::const_iterator const_iterator_type; 198 | 199 | typedef typename elem_type::type type; 200 | 201 | const_iterator_type ref; 202 | 203 | slice_const_iterator() {} 204 | slice_const_iterator(const const_iterator_type ©) : ref(copy) {} 205 | ~slice_const_iterator() {} 206 | 207 | operator bool() const 208 | { 209 | return (bool)ref && (bool)*ref; 210 | } 211 | 212 | operator typename const_iterator_type::type() const 213 | { 214 | return *ref; 215 | } 216 | 217 | type operator*() 218 | { 219 | return **ref; 220 | } 221 | 222 | type *operator->() 223 | { 224 | return &(**ref); 225 | } 226 | 227 | type *ptr() 228 | { 229 | return &(**ref); 230 | } 231 | 232 | type &get() 233 | { 234 | return **ref; 235 | } 236 | 237 | int idx() const 238 | { 239 | return ref.idx(); 240 | } 241 | 242 | slice_const_iterator operator++(int) 243 | { 244 | return ref++; 245 | } 246 | 247 | slice_const_iterator operator--(int) 248 | { 249 | return ref--; 250 | } 251 | 252 | slice_const_iterator &operator++() 253 | { 254 | ++ref; 255 | return *this; 256 | } 257 | 258 | slice_const_iterator &operator--() 259 | { 260 | ++ref; 261 | return *this; 262 | } 263 | 264 | slice_const_iterator &operator+=(int n) 265 | { 266 | ref += n; 267 | return *this; 268 | } 269 | 270 | slice_const_iterator &operator-=(int n) 271 | { 272 | ref -= n; 273 | return *this; 274 | } 275 | 276 | slice_const_iterator operator+(int n) const 277 | { 278 | return ref + n; 279 | } 280 | 281 | slice_const_iterator operator-(int n) const 282 | { 283 | return ref - n; 284 | } 285 | 286 | bool operator==(slice_iterator i) const 287 | { 288 | return ref == i.ref; 289 | } 290 | 291 | bool operator!=(slice_iterator i) const 292 | { 293 | return ref != i.ref; 294 | } 295 | 296 | bool operator==(slice_const_iterator i) const 297 | { 298 | return ref == i.ref; 299 | } 300 | 301 | bool operator!=(slice_const_iterator i) const 302 | { 303 | return ref != i.ref; 304 | } 305 | 306 | int operator-(slice_iterator i) const 307 | { 308 | return ref - i.ref; 309 | } 310 | 311 | int operator-(slice_const_iterator i) const 312 | { 313 | return ref - i.ref; 314 | } 315 | 316 | slice sub(int length) 317 | { 318 | return ref.subcpy(length); 319 | } 320 | 321 | slice subcpy(int length) 322 | { 323 | return ref.subcpy(length); 324 | } 325 | 326 | slice sub() 327 | { 328 | return ref.subcpy(); 329 | } 330 | 331 | slice subcpy() 332 | { 333 | return ref.subcpy(); 334 | } 335 | 336 | slice_const_iterator &operator=(slice_const_iterator i) 337 | { 338 | ref = i.ref; 339 | return *this; 340 | } 341 | }; 342 | 343 | template 344 | struct slice : container::type>::type, slice_iterator, slice_const_iterator > 345 | { 346 | typedef typename elem_type::type index_type; 347 | typedef container::type, slice_iterator, slice_const_iterator > super; 348 | 349 | using typename super::type; 350 | using typename super::iterator; 351 | using typename super::const_iterator; 352 | 353 | container_type ref; 354 | 355 | slice() {} 356 | slice(const_iterator left, const_iterator right) : ref(left.ref, right.ref) {} 357 | slice(iterator left, iterator right) : ref(left.ref, right.ref) {} 358 | 359 | template 360 | slice(const container_type2 ©) : ref(copy) {} 361 | 362 | ~slice() {} 363 | 364 | int size() const 365 | { 366 | return ref.size(); 367 | } 368 | 369 | iterator begin() 370 | { 371 | return iterator(ref.begin()); 372 | } 373 | 374 | iterator end() 375 | { 376 | return iterator(ref.end()); 377 | } 378 | 379 | iterator rbegin() 380 | { 381 | return iterator(ref.rbegin()); 382 | } 383 | 384 | iterator rend() 385 | { 386 | return iterator(ref.rend()); 387 | } 388 | 389 | const_iterator begin() const 390 | { 391 | return const_iterator(ref.begin()); 392 | } 393 | 394 | const_iterator end() const 395 | { 396 | return const_iterator(ref.end()); 397 | } 398 | 399 | const_iterator rbegin() const 400 | { 401 | return const_iterator(ref.rbegin()); 402 | } 403 | 404 | const_iterator rend() const 405 | { 406 | return const_iterator(ref.rend()); 407 | } 408 | 409 | iterator at(int i) 410 | { 411 | return iterator(ref.at(i)); 412 | } 413 | 414 | const_iterator at(int i) const 415 | { 416 | return const_iterator(ref.at(i)); 417 | } 418 | 419 | type &front() 420 | { 421 | return ref.front().get(); 422 | } 423 | 424 | type &back() 425 | { 426 | return ref.back().get(); 427 | } 428 | 429 | const type front() const 430 | { 431 | return ref.front().get(); 432 | } 433 | 434 | const type back() const 435 | { 436 | return ref.back().get(); 437 | } 438 | 439 | type &get(int i) 440 | { 441 | return ref.get(i).get(); 442 | } 443 | 444 | type *ptr(int i) 445 | { 446 | return ref.get(i).ptr(); 447 | } 448 | 449 | const type &get(int i) const 450 | { 451 | return ref.get(i).get(); 452 | } 453 | 454 | const type *ptr(int i) const 455 | { 456 | return ref.get(i).ptr(); 457 | } 458 | 459 | type &operator[](int i) 460 | { 461 | return ref.get(i).get(); 462 | } 463 | 464 | const type &operator[](int i) const 465 | { 466 | return ref.get(i).get(); 467 | } 468 | 469 | core::slice sub(int start, int end) const 470 | { 471 | typename container_type::const_iterator first = start < 0 ? ref.end() + start : ref.begin() + start; 472 | typename container_type::const_iterator last = end < 0 ? ref.end() + end : ref.begin() + end; 473 | return container_type(first, last); 474 | } 475 | 476 | core::slice subcpy(int start, int end) const 477 | { 478 | typename container_type::const_iterator first = start < 0 ? ref.end() + start : ref.begin() + start; 479 | typename container_type::const_iterator last = end < 0 ? ref.end() + end : ref.begin() + end; 480 | return container_type(first, last); 481 | } 482 | 483 | core::slice sub(int start) const 484 | { 485 | typename container_type::const_iterator first = start < 0 ? ref.end() + start : ref.begin() + start; 486 | return container_type(first, ref.end()); 487 | } 488 | 489 | core::slice subcpy(int start) const 490 | { 491 | typename container_type::const_iterator first = start < 0 ? ref.end() + start : ref.begin() + start; 492 | return container_type(first, ref.end()); 493 | } 494 | 495 | core::slice sub() const 496 | { 497 | return container_type(ref.begin(), ref.end()); 498 | } 499 | 500 | core::slice subcpy() const 501 | { 502 | return container_type(ref.begin(), ref.end()); 503 | } 504 | }; 505 | 506 | template 507 | slice > slice_t(iterator_type start, iterator_type end) 508 | { 509 | return range(start, end); 510 | } 511 | 512 | template 513 | slice > slice_t(slice_iterator > start, slice_iterator > end) 514 | { 515 | return range(start.ref.get(), end.ref.get()); 516 | } 517 | 518 | template 519 | slice deref(const container_type &c) 520 | { 521 | return c; 522 | } 523 | 524 | template 525 | slice deref(const range > &c) 526 | { 527 | return container_type(c.begin()->ref, c.end()->ref); 528 | } 529 | 530 | template 531 | container_type &ref(slice &c) 532 | { 533 | return c; 534 | } 535 | 536 | template 537 | container_type ref(const slice &c) 538 | { 539 | return c; 540 | } 541 | 542 | template 543 | typename container_type::iterator &ref(typename slice::iterator &i) 544 | { 545 | return i; 546 | } 547 | 548 | template 549 | typename container_type::iterator ref(const typename slice::iterator &i) 550 | { 551 | return i; 552 | } 553 | 554 | template 555 | typename container_type::const_iterator &ref(typename slice::const_iterator &i) 556 | { 557 | return i; 558 | } 559 | 560 | template 561 | typename container_type::const_iterator ref(const typename slice::const_iterator &i) 562 | { 563 | return i; 564 | } 565 | 566 | } 567 | 568 | -------------------------------------------------------------------------------- /std/sort.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sort.h 3 | * 4 | * Created on: Oct 7, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | namespace core 14 | { 15 | 16 | template 17 | void swap(type &t1, type &t2) 18 | { 19 | type temp = t1; 20 | t1 = t2; 21 | t2 = temp; 22 | } 23 | 24 | template 25 | type median_iterator(type t1, type t2, type t3) 26 | { 27 | if (*t1 < *t2) 28 | { 29 | if (*t2 < *t3) 30 | return t2; 31 | else if (*t3 < *t1) 32 | return t1; 33 | else 34 | return t3; 35 | } 36 | else 37 | { 38 | if (*t1 < *t3) 39 | return t1; 40 | else if (*t3 < *t2) 41 | return t2; 42 | else 43 | return t3; 44 | } 45 | } 46 | 47 | // Sorting Algorithms 48 | template 49 | container_type sort_selection(container_type c) 50 | { 51 | for (typename container_type::iterator i = c.begin(); i != c.end(); i++) 52 | { 53 | typename container_type::iterator max_j = i; 54 | for (typename container_type::iterator j = i+1; j != c.end(); j++) 55 | if (*j < *max_j) 56 | max_j = j; 57 | 58 | i.swap(max_j); 59 | } 60 | 61 | return c; 62 | } 63 | 64 | template 65 | container_type &sort_selection_inplace(container_type &c) 66 | { 67 | for (typename container_type::iterator i = c.begin(); i != c.end(); i++) 68 | { 69 | typename container_type::iterator max_j = i; 70 | for (typename container_type::iterator j = i+1; j != c.end(); j++) 71 | if (*j < *max_j) 72 | max_j = j; 73 | 74 | i.swap(max_j); 75 | } 76 | 77 | return c; 78 | } 79 | 80 | template 81 | typename container_type::iterator choseLast(range c) 82 | { 83 | return c.finish-1; 84 | } 85 | 86 | template 87 | typename container_type::iterator choseMid(range c) 88 | { 89 | return c.start + c.size()/2; 90 | } 91 | 92 | template 93 | typename container_type::iterator choseRand(range c) 94 | { 95 | return c.start + rand()%(c.finish-c.start); 96 | } 97 | 98 | template 99 | struct Sort { 100 | typedef typename container_type::iterator iterator; 101 | typedef iterator (*PivotFunc)(range); 102 | }; 103 | 104 | template 105 | container_type sort_quick(container_type c, typename Sort::PivotFunc chosePivot = &choseLast) 106 | { 107 | typedef range section_t; 108 | core::array stack; 109 | if (c.begin() != c.end() and c.begin()+1 != c.end()) 110 | stack.push_back(section_t(c.begin(), c.end())); 111 | 112 | while (stack.size() > 0) { 113 | section_t r = stack.back(); 114 | stack.drop_back(); 115 | 116 | if (r.start+2 == r.finish) { 117 | if (*r.start > *(r.start+1)) 118 | r.start.swap(r.start+1); 119 | } else { 120 | typename container_type::iterator pivot = chosePivot(r); 121 | if (pivot != r.finish-1) { 122 | pivot.swap(r.finish-1); 123 | pivot = r.finish-1; 124 | } 125 | 126 | typename container_type::iterator store = r.start; 127 | for (typename container_type::iterator i = r.start; i != pivot and i != r.finish; i++) 128 | if (*i < *pivot) 129 | { 130 | if (i != store) 131 | i.swap(store); 132 | store++; 133 | } 134 | 135 | if (store != pivot) { 136 | store.swap(pivot); 137 | pivot = store; 138 | } 139 | 140 | if (r.start != store and r.start+1 != store) 141 | stack.push_back(section_t(r.start, store)); 142 | store++; 143 | 144 | while (store != r.finish and *store == *pivot) 145 | store++; 146 | 147 | if (store != r.finish and store+1 != r.finish) 148 | stack.push_back(section_t(store, r.finish)); 149 | } 150 | } 151 | 152 | return c; 153 | } 154 | 155 | template 156 | container_type &sort_quick_inplace(container_type &c, typename Sort::PivotFunc chosePivot = &choseLast) 157 | { 158 | typedef range section_t; 159 | core::array stack; 160 | if (c.begin() != c.end() and c.begin()+1 != c.end()) 161 | stack.push_back(section_t(c.begin(), c.end())); 162 | 163 | while (stack.size() > 0) { 164 | section_t r = stack.back(); 165 | stack.drop_back(); 166 | 167 | if (r.start+2 == r.finish) { 168 | if (*r.start > *(r.start+1)) 169 | r.start.swap(r.start+1); 170 | } else { 171 | typename container_type::iterator pivot = chosePivot(r); 172 | if (pivot != r.finish-1) { 173 | pivot.swap(r.finish-1); 174 | pivot = r.finish-1; 175 | } 176 | 177 | typename container_type::iterator store = r.start; 178 | for (typename container_type::iterator i = r.start; i != pivot and i != r.finish; i++) 179 | if (*i < *pivot) 180 | { 181 | if (i != store) 182 | i.swap(store); 183 | store++; 184 | } 185 | 186 | if (store != pivot) { 187 | store.swap(pivot); 188 | pivot = store; 189 | } 190 | 191 | if (r.start != store and r.start+1 != store) 192 | stack.push_back(section_t(r.start, store)); 193 | store++; 194 | 195 | while (store != r.finish and *store == *pivot) 196 | store++; 197 | 198 | if (store != r.finish and store+1 != r.finish) 199 | stack.push_back(section_t(store, r.finish)); 200 | } 201 | } 202 | 203 | return c; 204 | } 205 | 206 | template 207 | container_type1 sort_merge(const container_type1 &c1, const container_type2 &c2) 208 | { 209 | container_type1 result; 210 | typename container_type1::const_iterator i = c1.begin(); 211 | typename container_type2::const_iterator j = c2.begin(); 212 | while (i != c1.end() && j != c2.end()) 213 | { 214 | if (*i < *j) 215 | { 216 | result.push_back(*i); 217 | i++; 218 | } 219 | else if (*j < *i) 220 | { 221 | result.push_back(*j); 222 | j++; 223 | } 224 | else 225 | { 226 | result.push_back(*i); 227 | result.push_back(*j); 228 | i++; 229 | j++; 230 | } 231 | } 232 | 233 | result.append_back(i.sub()); 234 | result.append_back(j.sub()); 235 | return result; 236 | } 237 | 238 | template 239 | container_type1 &sort_merge_inplace(container_type1 &c1, const container_type2 &c2) 240 | { 241 | typename container_type1::iterator i = c1.begin(); 242 | typename container_type2::const_iterator j = c2.begin(); 243 | while (i != c1.end() && j != c2.end()) 244 | { 245 | if (*i < *j) 246 | i++; 247 | else if (*j < *i) 248 | { 249 | i.push(*j); 250 | j++; 251 | } 252 | else 253 | { 254 | i++; 255 | i.push(*j); 256 | j++; 257 | } 258 | } 259 | 260 | c1.append_back(j.sub()); 261 | return c1; 262 | } 263 | 264 | template 265 | typename container_type::iterator sort_insert(container_type &c1, const element &c2) 266 | { 267 | typename container_type::iterator result = lower_bound(c1, c2); 268 | result.push(c2); 269 | return result-1; 270 | } 271 | 272 | template 273 | typename container_type::iterator sort_unique_insert(container_type &c1, const element &c2) 274 | { 275 | typename container_type::iterator result = lower_bound(c1, c2); 276 | if (result and c2 == result.get()) { 277 | return result; 278 | } else { 279 | result.push(c2); 280 | return result-1; 281 | } 282 | } 283 | 284 | template 285 | bool is_sorted(const container_type &c) 286 | { 287 | for (typename container_type::const_iterator i = c.begin(); i != c.rbegin(); i++) 288 | if (*(i+1) < *i) 289 | return false; 290 | 291 | return true; 292 | } 293 | 294 | template 295 | bool is_rsorted(const container_type &c) 296 | { 297 | for (typename container_type::const_iterator i = c.begin(); i != c.rbegin(); i++) 298 | if (*(i+1) > *i) 299 | return false; 300 | 301 | return true; 302 | } 303 | 304 | template 305 | container_type reverse(container_type c) 306 | { 307 | for (typename container_type::iterator i = c.begin(), j = c.rbegin(); i != j && i != j+1; i++, j--) 308 | i.swap(j); 309 | return c; 310 | } 311 | 312 | template 313 | container_type &reverse_inplace(container_type &c) 314 | { 315 | for (typename container_type::iterator i = c.begin(), j = c.rbegin(); i != j && i != j+1; i++, j--) 316 | i.swap(j); 317 | return c; 318 | } 319 | 320 | template 321 | container_type1 &sort_unique_merge_inplace(container_type1 &c1, const container_type2 &c2) 322 | { 323 | typename container_type2::const_iterator j = c2.begin(); 324 | if (j) { 325 | typename container_type1::iterator i = lower_bound(c1, *j); 326 | while (i != c1.end() && j != c2.end()) 327 | { 328 | if (*i < *j) 329 | i++; 330 | else if (*j < *i) 331 | { 332 | i.push(*j); 333 | j++; 334 | } 335 | else 336 | { 337 | i++; 338 | j++; 339 | } 340 | } 341 | 342 | c1.append_back(j.sub()); 343 | } 344 | return c1; 345 | } 346 | 347 | } 348 | 349 | -------------------------------------------------------------------------------- /std/stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * stream.cpp 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #include 9 | 10 | namespace core 11 | { 12 | 13 | flush_t::flush_t(const char *end) 14 | { 15 | this->end = end; 16 | } 17 | 18 | flush_t::~flush_t() 19 | { 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /std/stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stream.h 3 | * 4 | * Created on: Feb 5, 2014 5 | * Author: nbingham 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace core 13 | { 14 | 15 | struct flush_t 16 | { 17 | flush_t(const char *end = NULL); 18 | ~flush_t(); 19 | 20 | const char *end; 21 | }; 22 | 23 | template 24 | struct stream : file 25 | { 26 | stream() 27 | { 28 | } 29 | 30 | stream(int desc) : file(desc) 31 | { 32 | } 33 | 34 | stream(const char *name, unsigned char mode = file::rw, unsigned char owner = file::rw, unsigned char group = file::r, unsigned char user = file::r) : file(name, mode, owner, group, user) 35 | { 36 | } 37 | 38 | stream(array name, unsigned char mode = file::rw, unsigned char owner = file::rw, unsigned char group = file::r, unsigned char user = file::r) : file(name, mode, owner, group, user) 39 | { 40 | } 41 | 42 | ~stream() 43 | { 44 | } 45 | 46 | stream_type cache; 47 | }; 48 | 49 | template 50 | stream &operator<<(stream &str, value_type value) 51 | { 52 | str.cache << value; 53 | return str; 54 | } 55 | 56 | template 57 | stream &operator<<(stream &str, flush_t end) 58 | { 59 | if (end.end != NULL) 60 | str << end.end; 61 | str.write(str.cache); 62 | str.cache.clear(); 63 | return str; 64 | } 65 | 66 | template 67 | stream &operator>>(stream &str, value_type value) 68 | { 69 | str.cache >> value; 70 | return str; 71 | } 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /std/string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace core 8 | { 9 | 10 | struct string : array 11 | { 12 | string(); 13 | 14 | template 15 | string(const container &str) : array(str) 16 | { 17 | } 18 | 19 | string(const iterator &left, const iterator &right) : array(left, right) 20 | { 21 | } 22 | 23 | string(const string &str); 24 | 25 | string(const char *str); 26 | string(const char *str, int n); 27 | string(char str); 28 | 29 | ~string(); 30 | 31 | using array::size; 32 | 33 | using array::operator=; 34 | string &operator=(const char *str); 35 | string &operator=(char *str); 36 | 37 | string &operator+=(const char *str); 38 | string &operator+=(char *str); 39 | string &operator+=(const string &str); 40 | 41 | string escaped(); 42 | string unescaped(); 43 | 44 | char *c_str(); 45 | }; 46 | 47 | template 48 | struct options 49 | { 50 | options(const value_type &value, int radix) 51 | { 52 | this->value = &value; 53 | this->radix = radix; 54 | } 55 | 56 | ~options() {} 57 | 58 | const value_type *value; 59 | int radix; 60 | }; 61 | 62 | template 63 | options to_hex(const value_type &value) 64 | { 65 | return options(value, 16); 66 | } 67 | 68 | template 69 | options to_bin(const value_type &value) 70 | { 71 | return options(value, 2); 72 | } 73 | 74 | string operator+(const string &s1, const string &s2); 75 | string operator+(const string &s1, const char *s2); 76 | string operator+(const string &s1, char *s2); 77 | string operator+(const string &s1, char s2); 78 | 79 | string &operator<<(string &s1, char s2); 80 | string &operator<<(string &s1, bool s2); 81 | string &operator<<(string &s1, int s2); 82 | string &operator<<(string &s1, short s2); 83 | string &operator<<(string &s1, long s2); 84 | string &operator<<(string &s1, long long s2); 85 | string &operator<<(string &s1, unsigned char s2); 86 | string &operator<<(string &s1, unsigned int s2); 87 | string &operator<<(string &s1, unsigned short s2); 88 | string &operator<<(string &s1, unsigned long s2); 89 | string &operator<<(string &s1, unsigned long long s2); 90 | string &operator<<(string &s1, options s2); 91 | string &operator<<(string &s1, options s2); 92 | string &operator<<(string &s1, options s2); 93 | string &operator<<(string &s1, options s2); 94 | string &operator<<(string &s1, options s2); 95 | string &operator<<(string &s1, options s2); 96 | string &operator<<(string &s1, options s2); 97 | string &operator<<(string &s1, options s2); 98 | string &operator<<(string &s1, options s2); 99 | string &operator<<(string &s1, float s2); 100 | string &operator<<(string &s1, double s2); 101 | string &operator<<(string &s1, const string &s2); 102 | string &operator<<(string &s1, const char *s2); 103 | string &operator<<(string &s1, char *s2); 104 | 105 | string format_string(const string &str, const char *esc); 106 | 107 | template 108 | struct parsable 109 | { 110 | parsable(const type *val) : obj(val) {} 111 | ~parsable() {} 112 | 113 | const type *obj; 114 | }; 115 | 116 | template 117 | string &operator<<(string &s1, const container &v) 118 | { 119 | s1 << '{'; 120 | for (typename container::const_iterator i = v.begin(); i; i++) 121 | { 122 | if (i != v.begin()) 123 | s1 << ", "; 124 | s1 << parsable(i.ptr()); 125 | } 126 | s1 << '}'; 127 | return s1; 128 | } 129 | 130 | template 131 | string &operator<<(string &s1, const options &v) 132 | { 133 | s1 << '{'; 134 | for (typename container::const_iterator i = v.value->begin(); i; i++) 135 | { 136 | if (i != v.value->begin()) 137 | s1 << ", "; 138 | s1 << options >(parsable(i.ptr()), v.radix); 139 | } 140 | s1 << '}'; 141 | return s1; 142 | } 143 | 144 | template 145 | string &operator<<(string &s1, const parsable &p) 146 | { 147 | s1 << *p.obj; 148 | return s1; 149 | } 150 | 151 | template 152 | string &operator<<(string &s1, const options > &p) 153 | { 154 | s1 << options(*p.value->obj, p.radix); 155 | return s1; 156 | } 157 | 158 | template <> 159 | string &operator<<(string &s1, const parsable &p); 160 | 161 | template <> 162 | string &operator<<(string &s1, const options > &p); 163 | 164 | template 165 | string &operator<<(string &s1, const pair &v) 166 | { 167 | return s1 << '(' << parsable(&v.first) << ", " << parsable(&v.second) << ')'; 168 | } 169 | 170 | template 171 | string &operator<<(string &s1, const implier &v) 172 | { 173 | return s1 << parsable(&v.key) << ": " << parsable(&v.value); 174 | } 175 | 176 | template 177 | string &operator<<(string &s1, const options > &v) 178 | { 179 | return s1 << '(' << options >(parsable(&v.value->first), v.radix) << ", " << options >(parsable(&v.value->second), v.radix) << ')'; 180 | } 181 | 182 | template 183 | string &operator<<(string &s1, const options > &v) 184 | { 185 | return s1 << options >(parsable(&v.value->key), v.radix) << ": " << options >(parsable(&v.value->value), v.radix); 186 | } 187 | 188 | 189 | bool operator==(string s1, const char* s2); 190 | bool operator!=(string s1, const char* s2); 191 | bool operator<(string s1, const char* s2); 192 | bool operator>(string s1, const char* s2); 193 | bool operator<=(string s1, const char* s2); 194 | bool operator>=(string s1, const char* s2); 195 | bool operator==(const char* s1, string s2); 196 | bool operator!=(const char* s1, string s2); 197 | bool operator<(const char* s1, string s2); 198 | bool operator>(const char* s1, string s2); 199 | bool operator<=(const char* s1, string s2); 200 | bool operator>=(const char* s1, string s2); 201 | 202 | bool is_alpha(char c); 203 | bool is_numeric(char c); 204 | bool is_symbol(char c); 205 | bool is_whitespace(char c); 206 | 207 | int edit_distance(const string &s1, const string &s2); 208 | int get_column(const string &line, int index, int tab_width); 209 | string get_column_ptr(const string &line, int index); 210 | string line_wrap(const string &line, int length); 211 | 212 | int itoa(int value, char *str); 213 | int itoa(unsigned int value, char *str); 214 | int itoa(long long value, char *str); 215 | int itoa(unsigned long long value, char *str); 216 | int itob(unsigned int value, char *str); 217 | int itox(unsigned int value, char *str); 218 | 219 | int ftoa(float value, char *str); 220 | int ftoa(double value, char *str); 221 | 222 | slice > wrapstr(const char *cstr); 223 | slice > wrapstr(char *cstr); 224 | slice > wrapstr(const char *cstr, int n); 225 | slice > wrapstr(char *cstr, int n); 226 | 227 | } 228 | -------------------------------------------------------------------------------- /test/algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace core; 10 | 11 | TEST(algorithm, collapse) 12 | { 13 | array x; 14 | 15 | x = range(0, 10); 16 | EXPECT_EQ(x, range(0, 10)); 17 | collapse_inplace(x); 18 | EXPECT_EQ(x, range(0, 10)); 19 | 20 | x = fill(10, 4); 21 | EXPECT_EQ(x, fill(10, 4)); 22 | collapse_inplace(x); 23 | EXPECT_EQ(x, fill(1, 4)); 24 | 25 | x = array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5); 26 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 27 | collapse_inplace(x); 28 | EXPECT_EQ(x, array_t(7, 1, 2, 3, 4, 3, 4, 5)); 29 | 30 | array y; 31 | 32 | x = range(0, 10); 33 | EXPECT_EQ(x, range(0, 10)); 34 | y = collapse(x); 35 | EXPECT_EQ(x, range(0, 10)); 36 | EXPECT_EQ(y, range(0, 10)); 37 | 38 | x = fill(10, 4); 39 | EXPECT_EQ(x, fill(10, 4)); 40 | y = collapse(x); 41 | EXPECT_EQ(x, fill(10, 4)); 42 | EXPECT_EQ(y, fill(1, 4)); 43 | 44 | x = array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5); 45 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 46 | y = collapse(x); 47 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 48 | EXPECT_EQ(y, array_t(7, 1, 2, 3, 4, 3, 4, 5)); 49 | } 50 | 51 | TEST(algorithm, unique) 52 | { 53 | array x; 54 | 55 | x = range(0, 10); 56 | EXPECT_EQ(x, range(0, 10)); 57 | unique_inplace(x); 58 | EXPECT_EQ(x, range(0, 10)); 59 | 60 | x = fill(10, 4); 61 | EXPECT_EQ(x, fill(10, 4)); 62 | unique_inplace(x); 63 | EXPECT_EQ(x, fill(1, 4)); 64 | 65 | x = array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5); 66 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 67 | unique_inplace(x); 68 | EXPECT_EQ(x, array_t(5, 1, 2, 3, 4, 5)); 69 | 70 | array y; 71 | 72 | x = range(0, 10); 73 | EXPECT_EQ(x, range(0, 10)); 74 | y = unique(x); 75 | EXPECT_EQ(x, range(0, 10)); 76 | EXPECT_EQ(y, range(0, 10)); 77 | 78 | x = fill(10, 4); 79 | EXPECT_EQ(x, fill(10, 4)); 80 | y = unique(x); 81 | EXPECT_EQ(x, fill(10, 4)); 82 | EXPECT_EQ(y, fill(1, 4)); 83 | 84 | x = array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5); 85 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 86 | y = unique(x); 87 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 3, 3, 4, 3, 4, 5, 5)); 88 | EXPECT_EQ(y, array_t(5, 1, 2, 3, 4, 5)); 89 | } 90 | 91 | TEST(algorithm, intersection) 92 | { 93 | array x = array_t(5, 1, 3, 5, 7, 9); 94 | array y = array_t(5, 2, 4, 6, 7, 8); 95 | array z = array_t(5, 1, 4, 7, 9, 10); 96 | array w = array_t(3, 11, 12, 13); 97 | 98 | EXPECT_EQ(intersection(x, y), array_t(1, 7)); 99 | EXPECT_EQ(intersection(y, z), array_t(2, 4, 7)); 100 | EXPECT_EQ(intersection(x, z), array_t(3, 1, 7, 9)); 101 | EXPECT_EQ(intersection(x, y, z), array_t(1, 7)); 102 | EXPECT_EQ(intersection(x, w), array()); 103 | 104 | array > q; 105 | q.push_back(x); 106 | q.push_back(y); 107 | q.push_back(z); 108 | EXPECT_EQ(intersection(q), array_t(1, 7)); 109 | } 110 | 111 | TEST(algorithm, intersection_size) 112 | { 113 | array x = array_t(5, 1, 3, 5, 7, 9); 114 | array y = array_t(5, 2, 4, 6, 7, 8); 115 | array z = array_t(5, 1, 4, 7, 9, 10); 116 | array w = array_t(3, 11, 12, 13); 117 | 118 | EXPECT_EQ(intersection_size(x, y), 1); 119 | EXPECT_EQ(intersection_size(y, z), 2); 120 | EXPECT_EQ(intersection_size(x, z), 3); 121 | EXPECT_EQ(intersection_size(x, y, z), 1); 122 | EXPECT_EQ(intersection_size(x, w), 0); 123 | 124 | array > q; 125 | q.push_back(x); 126 | q.push_back(y); 127 | q.push_back(z); 128 | EXPECT_EQ(intersection_size(q), 1); 129 | } 130 | 131 | TEST(algorithm, intersects) 132 | { 133 | array x = array_t(5, 1, 3, 5, 7, 9); 134 | array y = array_t(5, 2, 4, 6, 7, 8); 135 | array z = array_t(5, 1, 4, 7, 9, 10); 136 | array w = array_t(3, 11, 12, 13); 137 | 138 | EXPECT_TRUE(intersects(x, y)); 139 | EXPECT_TRUE(intersects(y, z)); 140 | EXPECT_TRUE(intersects(x, z)); 141 | EXPECT_TRUE(intersects(x, y, z)); 142 | EXPECT_FALSE(intersects(x, w)); 143 | 144 | array > q; 145 | q.push_back(x); 146 | q.push_back(y); 147 | q.push_back(z); 148 | EXPECT_TRUE(intersects(q)); 149 | } 150 | 151 | TEST(algorithm, symmetric_compliment) 152 | { 153 | array y = array_t(5, 2, 4, 6, 7, 8); 154 | array z = array_t(5, 1, 4, 7, 9, 10); 155 | 156 | symmetric_compliment(y, z); 157 | EXPECT_EQ(y, array_t(3, 2, 6, 8)); 158 | EXPECT_EQ(z, array_t(3, 1, 9, 10)); 159 | 160 | y = array_t(5, 1, 2, 3, 4, 5); 161 | z = array_t(5, 6, 7, 8, 9, 10); 162 | 163 | symmetric_compliment(y, z); 164 | EXPECT_EQ(y, array_t(5, 1, 2, 3, 4, 5)); 165 | EXPECT_EQ(z, array_t(5, 6, 7, 8, 9, 10)); 166 | } 167 | 168 | TEST(algorithm, difference) 169 | { 170 | array y = array_t(5, 2, 4, 6, 7, 8); 171 | array z = array_t(5, 1, 4, 7, 9, 10); 172 | 173 | EXPECT_EQ(difference(y, z), array_t(3, 2, 6, 8)); 174 | EXPECT_EQ(difference(z, y), array_t(3, 1, 9, 10)); 175 | 176 | y = array_t(5, 1, 2, 3, 4, 5); 177 | z = array_t(5, 6, 7, 8, 9, 10); 178 | 179 | EXPECT_EQ(difference(y, z), array_t(5, 1, 2, 3, 4, 5)); 180 | EXPECT_EQ(difference(z, y), array_t(5, 6, 7, 8, 9, 10)); 181 | } 182 | 183 | TEST(algorithm, remove) 184 | { 185 | array y = array_t(7, 2, 4, 6, 2, 7, 8, 8); 186 | EXPECT_EQ(y, array_t(7, 2, 4, 6, 2, 7, 8, 8)); 187 | remove(y, 2); 188 | EXPECT_EQ(y, array_t(5, 4, 6, 7, 8, 8)); 189 | remove(y, 7); 190 | EXPECT_EQ(y, array_t(4, 4, 6, 8, 8)); 191 | remove(y, 8); 192 | EXPECT_EQ(y, array_t(2, 4, 6)); 193 | remove(y, 4); 194 | EXPECT_EQ(y, array_t(1, 6)); 195 | remove(y, 6); 196 | EXPECT_EQ(y, array()); 197 | } 198 | -------------------------------------------------------------------------------- /test/fill_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(fill_iterator, iterate) 8 | { 9 | fill x(10, 5); 10 | 11 | int j = 0; 12 | for (fill::iterator i = x.begin(); i; i++) 13 | { 14 | EXPECT_EQ(5, *i); 15 | j++; 16 | } 17 | EXPECT_EQ(10, j); 18 | } 19 | 20 | 21 | TEST(fill_iterator, index) 22 | { 23 | fill x(10, 5); 24 | 25 | EXPECT_EQ(5, *x.at(0)); 26 | EXPECT_EQ(5, *x.at(2)); 27 | EXPECT_EQ(5, *x.at(-1)); 28 | EXPECT_EQ(5, *x.at(-3)); 29 | 30 | EXPECT_EQ(5, x.at(0).get()); 31 | EXPECT_EQ(5, x.at(2).get()); 32 | EXPECT_EQ(5, x.at(-1).get()); 33 | EXPECT_EQ(5, x.at(-3).get()); 34 | 35 | EXPECT_EQ(0, x.at(0).idx()); 36 | EXPECT_EQ(2, x.at(2).idx()); 37 | EXPECT_EQ(x.size()-1, x.at(-1).idx()); 38 | EXPECT_EQ(x.size()-3, x.at(-3).idx()); 39 | } 40 | 41 | TEST(fill_iterator, sub) 42 | { 43 | fill x(10, 5); 44 | EXPECT_EQ(x.at(4).sub(3), fill(3, 5)); 45 | EXPECT_EQ(x.at(7).sub(-3), fill(3, 5)); 46 | EXPECT_EQ(x.at(4).sub(), fill(6, 5)); 47 | EXPECT_EQ(x.at(4).subcpy(3), fill(3, 5)); 48 | EXPECT_EQ(x.at(7).subcpy(-3), fill(3, 5)); 49 | EXPECT_EQ(x.at(4).subcpy(), fill(6, 5)); 50 | } 51 | -------------------------------------------------------------------------------- /test/fill_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(fill_struct, base_constructor) 8 | { 9 | fill x(20, 10); 10 | EXPECT_EQ(20, x.count); 11 | EXPECT_EQ(10, x.value); 12 | } 13 | 14 | TEST(fill_struct, copy_constructor) 15 | { 16 | fill y(5, 10); 17 | fill x(y); 18 | EXPECT_EQ(x, y); 19 | } 20 | 21 | TEST(fill_struct, index) 22 | { 23 | fill x(8, 5); 24 | 25 | EXPECT_EQ(8, x.size()); 26 | 27 | EXPECT_EQ(5, *x.at(0)); 28 | EXPECT_EQ(5, *x.at(2)); 29 | EXPECT_EQ(5, *x.at(-1)); 30 | EXPECT_EQ(5, *x.at(-3)); 31 | 32 | EXPECT_EQ(5, x.get(0)); 33 | EXPECT_EQ(5, x.get(2)); 34 | EXPECT_EQ(5, x.get(-1)); 35 | EXPECT_EQ(5, x.get(-3)); 36 | 37 | EXPECT_EQ(5, x[0]); 38 | EXPECT_EQ(5, x[2]); 39 | EXPECT_EQ(5, x[-1]); 40 | EXPECT_EQ(5, x[-3]); 41 | 42 | EXPECT_EQ(5, x.front()); 43 | EXPECT_EQ(5, x.back()); 44 | 45 | EXPECT_EQ(5, *x.begin()); 46 | EXPECT_EQ(5, *x.rbegin()); 47 | } 48 | 49 | TEST(fill_struct, sub) 50 | { 51 | fill x(8, 5); 52 | fill y(4, 5); 53 | 54 | // positive start and end 55 | EXPECT_EQ(y, x.sub(2, 6)); 56 | EXPECT_EQ(y, x.subcpy(2, 6)); 57 | 58 | // positive start, negative end 59 | EXPECT_EQ(y, x.sub(2, -2)); 60 | EXPECT_EQ(y, x.subcpy(2, -2)); 61 | 62 | // negative start and end 63 | EXPECT_EQ(y, x.sub(-6, -2)); 64 | EXPECT_EQ(y, x.subcpy(-6, -2)); 65 | 66 | // negative start, positive end 67 | EXPECT_EQ(y, x.sub(-6, 6)); 68 | EXPECT_EQ(y, x.subcpy(-6, 6)); 69 | 70 | // single input 71 | EXPECT_EQ(y, x.sub(4)); 72 | EXPECT_EQ(y, x.sub(-4)); 73 | EXPECT_EQ(y, x.subcpy(4)); 74 | EXPECT_EQ(y, x.subcpy(-4)); 75 | 76 | // ref 77 | EXPECT_EQ(x, x.sub()); 78 | EXPECT_EQ(y, y.sub()); 79 | } 80 | 81 | TEST(fill_struct, swap) 82 | { 83 | fill x(10, 10); 84 | fill y(8, 5); 85 | EXPECT_EQ(fill(10, 10), x); 86 | EXPECT_EQ(fill(8, 5), y); 87 | x.swap(y); 88 | EXPECT_EQ(fill(10, 10), y); 89 | EXPECT_EQ(fill(8, 5), x); 90 | } 91 | 92 | TEST(fill_struct, compare) 93 | { 94 | fill x(10, 5); 95 | fill y(10, 6); 96 | 97 | EXPECT_TRUE(x < y); 98 | EXPECT_FALSE(x > y); 99 | EXPECT_TRUE(x <= y); 100 | EXPECT_FALSE(x >= y); 101 | EXPECT_FALSE(x == y); 102 | EXPECT_TRUE(x != y); 103 | 104 | x = fill(9, 5); 105 | y = fill(10, 5); 106 | 107 | EXPECT_TRUE(x < y); 108 | EXPECT_FALSE(x > y); 109 | EXPECT_TRUE(x <= y); 110 | EXPECT_FALSE(x >= y); 111 | EXPECT_FALSE(x == y); 112 | EXPECT_TRUE(x != y); 113 | 114 | x = y; 115 | 116 | EXPECT_FALSE(x < y); 117 | EXPECT_FALSE(x > y); 118 | EXPECT_TRUE(x <= y); 119 | EXPECT_TRUE(x >= y); 120 | EXPECT_TRUE(x == y); 121 | EXPECT_FALSE(x != y); 122 | 123 | x = fill(10, 5); 124 | y = fill(9, 6); 125 | 126 | EXPECT_TRUE(x < y); 127 | EXPECT_FALSE(x > y); 128 | EXPECT_TRUE(x <= y); 129 | EXPECT_FALSE(x >= y); 130 | EXPECT_FALSE(x == y); 131 | EXPECT_TRUE(x != y); 132 | 133 | x = fill(10, 5); 134 | y = fill(9, 4); 135 | 136 | EXPECT_FALSE(x < y); 137 | EXPECT_TRUE(x > y); 138 | EXPECT_FALSE(x <= y); 139 | EXPECT_TRUE(x >= y); 140 | EXPECT_FALSE(x == y); 141 | EXPECT_TRUE(x != y); 142 | } 143 | -------------------------------------------------------------------------------- /test/filter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace core; 9 | 10 | TEST(search, filter) 11 | { 12 | array x = array_t(10, 2, 8, 5, 3, 5, 7, 4, 2, 8, 5); 13 | EXPECT_EQ(filter(x, 2).idx(), array_t(2, 0, 7)); 14 | EXPECT_EQ(filter(x, 8).idx(), array_t(2, 1, 8)); 15 | EXPECT_EQ(filter(x, 5).idx(), array_t(3, 2, 4, 9)); 16 | EXPECT_EQ(filter(x, 3).idx(), array_t(1, 3)); 17 | EXPECT_EQ(filter(x, 7).idx(), array_t(1, 5)); 18 | EXPECT_EQ(filter(x, 4).idx(), array_t(1, 6)); 19 | 20 | EXPECT_EQ(filter(x, 0).idx(), array()); 21 | EXPECT_EQ(filter(x, 1).idx(), array()); 22 | EXPECT_EQ(filter(x, 9).idx(), array()); 23 | 24 | slice::iterator> > y = x.sub(); 25 | EXPECT_EQ(filter(y, 2).idx(), array_t(2, 0, 7)); 26 | EXPECT_EQ(filter(y, 8).idx(), array_t(2, 1, 8)); 27 | EXPECT_EQ(filter(y, 5).idx(), array_t(3, 2, 4, 9)); 28 | EXPECT_EQ(filter(y, 3).idx(), array_t(1, 3)); 29 | EXPECT_EQ(filter(y, 7).idx(), array_t(1, 5)); 30 | EXPECT_EQ(filter(y, 4).idx(), array_t(1, 6)); 31 | 32 | EXPECT_EQ(filter(y, 0).idx(), array()); 33 | EXPECT_EQ(filter(y, 1).idx(), array()); 34 | EXPECT_EQ(filter(y, 9).idx(), array()); 35 | 36 | const array &z = x; 37 | EXPECT_EQ(filter(z, 2).idx(), array_t(2, 0, 7)); 38 | EXPECT_EQ(filter(z, 8).idx(), array_t(2, 1, 8)); 39 | EXPECT_EQ(filter(z, 5).idx(), array_t(3, 2, 4, 9)); 40 | EXPECT_EQ(filter(z, 3).idx(), array_t(1, 3)); 41 | EXPECT_EQ(filter(z, 7).idx(), array_t(1, 5)); 42 | EXPECT_EQ(filter(z, 4).idx(), array_t(1, 6)); 43 | 44 | EXPECT_EQ(filter(z, 0).idx(), array()); 45 | EXPECT_EQ(filter(z, 1).idx(), array()); 46 | EXPECT_EQ(filter(z, 9).idx(), array()); 47 | } 48 | 49 | TEST(search, filter_each) 50 | { 51 | array x = array_t(10, 2, 8, 5, 3, 5, 7, 4, 2, 8, 5); 52 | EXPECT_EQ(filter_each(x, range(2, 5)).idx(), array_t(4, 0, 3, 6, 7)); 53 | EXPECT_EQ(filter_each(x, range(7, 10)).idx(), array_t(3, 1, 5, 8)); 54 | EXPECT_EQ(filter_each(x, range(6, 8)).idx(), array_t(1, 5)); 55 | EXPECT_EQ(filter_each(x, array_t(3, 4, 3, 1)).idx(), array_t(2, 3, 6)); 56 | EXPECT_EQ(filter_each(x, array_t(3, 7, 4, 7)).idx(), array_t(2, 5, 6)); 57 | EXPECT_EQ(filter_each(x, array_t(3, 2, 8, 5)).idx(), array_t(7, 0, 1, 2, 4, 7, 8, 9)); 58 | 59 | EXPECT_EQ(filter_each(x, array()).idx(), array()); 60 | EXPECT_EQ(filter_each(x, array_t(3, 0, 1, 9)).idx(), array()); 61 | EXPECT_EQ(filter_each(x, array_t(3, 10, 11, 12)).idx(), array()); 62 | EXPECT_EQ(filter_each(x, array_t(3, -1, 6, 9)).idx(), array()); 63 | 64 | slice::iterator> > y = x.sub(); 65 | EXPECT_EQ(filter_each(y, range(2, 5)).idx(), array_t(4, 0, 3, 6, 7)); 66 | EXPECT_EQ(filter_each(y, range(7, 10)).idx(), array_t(3, 1, 5, 8)); 67 | EXPECT_EQ(filter_each(y, range(6, 8)).idx(), array_t(1, 5)); 68 | EXPECT_EQ(filter_each(y, array_t(3, 4, 3, 1)).idx(), array_t(2, 3, 6)); 69 | EXPECT_EQ(filter_each(y, array_t(3, 7, 4, 7)).idx(), array_t(2, 5, 6)); 70 | EXPECT_EQ(filter_each(y, array_t(3, 2, 8, 5)).idx(), array_t(7, 0, 1, 2, 4, 7, 8, 9)); 71 | 72 | EXPECT_EQ(filter_each(y, array()).idx(), array()); 73 | EXPECT_EQ(filter_each(y, array_t(3, 0, 1, 9)).idx(), array()); 74 | EXPECT_EQ(filter_each(y, array_t(3, 10, 11, 12)).idx(), array()); 75 | EXPECT_EQ(filter_each(y, array_t(3, -1, 6, 9)).idx(), array()); 76 | 77 | const array &z = x; 78 | EXPECT_EQ(filter_each(z, range(2, 5)).idx(), array_t(4, 0, 3, 6, 7)); 79 | EXPECT_EQ(filter_each(z, range(7, 10)).idx(), array_t(3, 1, 5, 8)); 80 | EXPECT_EQ(filter_each(z, range(6, 8)).idx(), array_t(1, 5)); 81 | EXPECT_EQ(filter_each(z, array_t(3, 4, 3, 1)).idx(), array_t(2, 3, 6)); 82 | EXPECT_EQ(filter_each(z, array_t(3, 7, 4, 7)).idx(), array_t(2, 5, 6)); 83 | EXPECT_EQ(filter_each(z, array_t(3, 2, 8, 5)).idx(), array_t(7, 0, 1, 2, 4, 7, 8, 9)); 84 | 85 | EXPECT_EQ(filter_each(z, array()).idx(), array()); 86 | EXPECT_EQ(filter_each(z, array_t(3, 0, 1, 9)).idx(), array()); 87 | EXPECT_EQ(filter_each(z, array_t(3, 10, 11, 12)).idx(), array()); 88 | EXPECT_EQ(filter_each(z, array_t(3, -1, 6, 9)).idx(), array()); 89 | } 90 | 91 | TEST(search, filter_pattern) 92 | { 93 | array x = array_t(10, 2, 8, 5, 3, 5, 7, 4, 2, 8, 5); 94 | EXPECT_EQ(filter_pattern(x, array_t(3, 2, 8, 5)).idx(), array_t(2, 0, 7)); 95 | EXPECT_EQ(filter_pattern(x, array_t(2, 8, 5)).idx(), array_t(2, 1, 8)); 96 | EXPECT_EQ(filter_pattern(x, array_t(1, 5)).idx(), array_t(3, 2, 4, 9)); 97 | EXPECT_EQ(filter_pattern(x, array_t(3, 3, 5, 7)).idx(), array_t(1, 3)); 98 | EXPECT_EQ(filter_pattern(x, array_t(3, 5, 7, 4)).idx(), array_t(1, 4)); 99 | EXPECT_EQ(filter_pattern(x, array_t(4, 4, 2, 8, 5)).idx(), array_t(1, 6)); 100 | 101 | EXPECT_EQ(filter_pattern(x, array()).idx(), range(0, 10)); 102 | EXPECT_EQ(filter_pattern(x, array_t(1, 1)).idx(), array()); 103 | EXPECT_EQ(filter_pattern(x, array_t(3, 8, 5, 4)).idx(), array()); 104 | 105 | slice::iterator> > y = x.sub(); 106 | EXPECT_EQ(filter_pattern(y, array_t(3, 2, 8, 5)).idx(), array_t(2, 0, 7)); 107 | EXPECT_EQ(filter_pattern(y, array_t(2, 8, 5)).idx(), array_t(2, 1, 8)); 108 | EXPECT_EQ(filter_pattern(y, array_t(1, 5)).idx(), array_t(3, 2, 4, 9)); 109 | EXPECT_EQ(filter_pattern(y, array_t(3, 3, 5, 7)).idx(), array_t(1, 3)); 110 | EXPECT_EQ(filter_pattern(y, array_t(3, 5, 7, 4)).idx(), array_t(1, 4)); 111 | EXPECT_EQ(filter_pattern(y, array_t(4, 4, 2, 8, 5)).idx(), array_t(1, 6)); 112 | 113 | EXPECT_EQ(filter_pattern(y, array()).idx(), range(0, 10)); 114 | EXPECT_EQ(filter_pattern(y, array_t(1, 1)).idx(), array()); 115 | EXPECT_EQ(filter_pattern(y, array_t(3, 8, 5, 4)).idx(), array()); 116 | 117 | const array &z = x; 118 | EXPECT_EQ(filter_pattern(z, array_t(3, 2, 8, 5)).idx(), array_t(2, 0, 7)); 119 | EXPECT_EQ(filter_pattern(z, array_t(2, 8, 5)).idx(), array_t(2, 1, 8)); 120 | EXPECT_EQ(filter_pattern(z, array_t(1, 5)).idx(), array_t(3, 2, 4, 9)); 121 | EXPECT_EQ(filter_pattern(z, array_t(3, 3, 5, 7)).idx(), array_t(1, 3)); 122 | EXPECT_EQ(filter_pattern(z, array_t(3, 5, 7, 4)).idx(), array_t(1, 4)); 123 | EXPECT_EQ(filter_pattern(z, array_t(4, 4, 2, 8, 5)).idx(), array_t(1, 6)); 124 | 125 | EXPECT_EQ(filter_pattern(z, array()).idx(), range(0, 10)); 126 | EXPECT_EQ(filter_pattern(z, array_t(1, 1)).idx(), array()); 127 | EXPECT_EQ(filter_pattern(z, array_t(3, 8, 5, 4)).idx(), array()); 128 | } 129 | 130 | 131 | -------------------------------------------------------------------------------- /test/graph_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(graph_iterator, link) 8 | { 9 | graph g; 10 | 11 | graph::iterator i0 = g.insert(5); 12 | graph::iterator i1 = g.insert(10); 13 | graph::iterator i2 = g.insert(3); 14 | graph::iterator i3 = g.insert(6); 15 | 16 | array::iterator> empty; 17 | 18 | EXPECT_EQ(i0.next(), empty); 19 | EXPECT_EQ(i1.next(), empty); 20 | EXPECT_EQ(i2.next(), empty); 21 | EXPECT_EQ(i3.next(), empty); 22 | EXPECT_EQ(i0.prev(), empty); 23 | EXPECT_EQ(i1.prev(), empty); 24 | EXPECT_EQ(i2.prev(), empty); 25 | EXPECT_EQ(i3.prev(), empty); 26 | 27 | 28 | array::iterator> i0next; 29 | i0next.push_back(i1); 30 | 31 | array::iterator> i1next; 32 | i1next.push_back(i2); 33 | 34 | array::iterator> i2next; 35 | i2next.push_back(i3); 36 | 37 | array::iterator> i3next; 38 | i3next.push_back(i0); 39 | 40 | array::iterator> i0prev; 41 | i0prev.push_back(i3); 42 | 43 | array::iterator> i1prev; 44 | i1prev.push_back(i0); 45 | 46 | array::iterator> i2prev; 47 | i2prev.push_back(i1); 48 | 49 | array::iterator> i3prev; 50 | i3prev.push_back(i2); 51 | 52 | i0.link(i1); 53 | EXPECT_EQ(i0.next(), i0next); 54 | EXPECT_EQ(i1.next(), empty); 55 | EXPECT_EQ(i2.next(), empty); 56 | EXPECT_EQ(i3.next(), empty); 57 | EXPECT_EQ(i0.prev(), empty); 58 | EXPECT_EQ(i1.prev(), i1prev); 59 | EXPECT_EQ(i2.prev(), empty); 60 | EXPECT_EQ(i3.prev(), empty); 61 | 62 | i1.link(i2); 63 | EXPECT_EQ(i0.next(), i0next); 64 | EXPECT_EQ(i1.next(), i1next); 65 | EXPECT_EQ(i2.next(), empty); 66 | EXPECT_EQ(i3.next(), empty); 67 | EXPECT_EQ(i0.prev(), empty); 68 | EXPECT_EQ(i1.prev(), i1prev); 69 | EXPECT_EQ(i2.prev(), i2prev); 70 | EXPECT_EQ(i3.prev(), empty); 71 | 72 | i2.link(i3); 73 | EXPECT_EQ(i0.next(), i0next); 74 | EXPECT_EQ(i1.next(), i1next); 75 | EXPECT_EQ(i2.next(), i2next); 76 | EXPECT_EQ(i3.next(), empty); 77 | EXPECT_EQ(i0.prev(), empty); 78 | EXPECT_EQ(i1.prev(), i1prev); 79 | EXPECT_EQ(i2.prev(), i2prev); 80 | EXPECT_EQ(i3.prev(), i3prev); 81 | 82 | i3.link(i0); 83 | EXPECT_EQ(i0.next(), i0next); 84 | EXPECT_EQ(i1.next(), i1next); 85 | EXPECT_EQ(i2.next(), i2next); 86 | EXPECT_EQ(i3.next(), i3next); 87 | EXPECT_EQ(i0.prev(), i0prev); 88 | EXPECT_EQ(i1.prev(), i1prev); 89 | EXPECT_EQ(i2.prev(), i2prev); 90 | EXPECT_EQ(i3.prev(), i3prev); 91 | } 92 | 93 | TEST(graph_iterator, pop) 94 | { 95 | graph g; 96 | 97 | graph::iterator i0 = g.insert(5); 98 | graph::iterator i1 = g.insert(10); 99 | graph::iterator i2 = g.insert(3); 100 | graph::iterator i3 = g.insert(6); 101 | 102 | i0.link(i1); 103 | i1.link(i2); 104 | i2.link(i3); 105 | i3.link(i0); 106 | 107 | array::iterator> empty; 108 | 109 | array::iterator> i0next; 110 | i0next.push_back(i1); 111 | 112 | array::iterator> i1next; 113 | i1next.push_back(i2); 114 | 115 | array::iterator> i2next; 116 | i2next.push_back(i3); 117 | 118 | array::iterator> i3next; 119 | i3next.push_back(i0); 120 | 121 | array::iterator> i0prev; 122 | i0prev.push_back(i3); 123 | 124 | array::iterator> i1prev; 125 | i1prev.push_back(i0); 126 | 127 | array::iterator> i2prev; 128 | i2prev.push_back(i1); 129 | 130 | array::iterator> i3prev; 131 | i3prev.push_back(i2); 132 | 133 | EXPECT_EQ(i0.next(), i0next); 134 | EXPECT_EQ(i1.next(), i1next); 135 | EXPECT_EQ(i2.next(), i2next); 136 | EXPECT_EQ(i3.next(), i3next); 137 | EXPECT_EQ(i0.prev(), i0prev); 138 | EXPECT_EQ(i1.prev(), i1prev); 139 | EXPECT_EQ(i2.prev(), i2prev); 140 | EXPECT_EQ(i3.prev(), i3prev); 141 | 142 | EXPECT_EQ(i2.pop(), 3); 143 | 144 | EXPECT_EQ(i0.next(), i0next); 145 | EXPECT_EQ(i1.next(), empty); 146 | EXPECT_EQ(i3.next(), i3next); 147 | EXPECT_EQ(i0.prev(), i0prev); 148 | EXPECT_EQ(i1.prev(), i1prev); 149 | EXPECT_EQ(i3.prev(), empty); 150 | 151 | EXPECT_EQ(i0.pop(), 5); 152 | 153 | EXPECT_EQ(i1.next(), empty); 154 | EXPECT_EQ(i3.next(), empty); 155 | EXPECT_EQ(i1.prev(), empty); 156 | EXPECT_EQ(i3.prev(), empty); 157 | 158 | EXPECT_EQ(i1.pop(), 10); 159 | 160 | EXPECT_EQ(i3.next(), empty); 161 | EXPECT_EQ(i3.prev(), empty); 162 | 163 | EXPECT_EQ(i3.pop(), 6); 164 | 165 | EXPECT_EQ(g.left.right, &g.right); 166 | EXPECT_EQ(g.right.left, &g.left); 167 | } 168 | 169 | TEST(graph_iterator, drop) 170 | { 171 | graph g; 172 | 173 | graph::iterator i0 = g.insert(5); 174 | graph::iterator i1 = g.insert(10); 175 | graph::iterator i2 = g.insert(3); 176 | graph::iterator i3 = g.insert(6); 177 | 178 | i0.link(i1); 179 | i1.link(i2); 180 | i2.link(i3); 181 | i3.link(i0); 182 | 183 | array::iterator> empty; 184 | 185 | array::iterator> i0next; 186 | i0next.push_back(i1); 187 | 188 | array::iterator> i1next; 189 | i1next.push_back(i2); 190 | 191 | array::iterator> i2next; 192 | i2next.push_back(i3); 193 | 194 | array::iterator> i3next; 195 | i3next.push_back(i0); 196 | 197 | array::iterator> i0prev; 198 | i0prev.push_back(i3); 199 | 200 | array::iterator> i1prev; 201 | i1prev.push_back(i0); 202 | 203 | array::iterator> i2prev; 204 | i2prev.push_back(i1); 205 | 206 | array::iterator> i3prev; 207 | i3prev.push_back(i2); 208 | 209 | EXPECT_EQ(i0.next(), i0next); 210 | EXPECT_EQ(i1.next(), i1next); 211 | EXPECT_EQ(i2.next(), i2next); 212 | EXPECT_EQ(i3.next(), i3next); 213 | EXPECT_EQ(i0.prev(), i0prev); 214 | EXPECT_EQ(i1.prev(), i1prev); 215 | EXPECT_EQ(i2.prev(), i2prev); 216 | EXPECT_EQ(i3.prev(), i3prev); 217 | 218 | i2.drop(); 219 | 220 | EXPECT_EQ(i0.next(), i0next); 221 | EXPECT_EQ(i1.next(), empty); 222 | EXPECT_EQ(i3.next(), i3next); 223 | EXPECT_EQ(i0.prev(), i0prev); 224 | EXPECT_EQ(i1.prev(), i1prev); 225 | EXPECT_EQ(i3.prev(), empty); 226 | 227 | i0.drop(); 228 | 229 | EXPECT_EQ(i1.next(), empty); 230 | EXPECT_EQ(i3.next(), empty); 231 | EXPECT_EQ(i1.prev(), empty); 232 | EXPECT_EQ(i3.prev(), empty); 233 | 234 | i1.drop(); 235 | 236 | EXPECT_EQ(i3.next(), empty); 237 | EXPECT_EQ(i3.prev(), empty); 238 | 239 | i3.drop(); 240 | 241 | EXPECT_EQ(g.left.right, &g.right); 242 | EXPECT_EQ(g.right.left, &g.left); 243 | } 244 | 245 | TEST(graph_iterator, unlink) 246 | { 247 | graph g; 248 | 249 | graph::iterator i0 = g.insert(5); 250 | graph::iterator i1 = g.insert(10); 251 | graph::iterator i2 = g.insert(3); 252 | graph::iterator i3 = g.insert(6); 253 | 254 | i0.link(i1); 255 | i1.link(i2); 256 | i2.link(i3); 257 | i3.link(i0); 258 | 259 | array::iterator> empty; 260 | 261 | array::iterator> i0next; 262 | i0next.push_back(i1); 263 | 264 | array::iterator> i1next; 265 | i1next.push_back(i2); 266 | 267 | array::iterator> i2next; 268 | i2next.push_back(i3); 269 | 270 | array::iterator> i3next; 271 | i3next.push_back(i0); 272 | 273 | array::iterator> i0prev; 274 | i0prev.push_back(i3); 275 | 276 | array::iterator> i1prev; 277 | i1prev.push_back(i0); 278 | 279 | array::iterator> i2prev; 280 | i2prev.push_back(i1); 281 | 282 | array::iterator> i3prev; 283 | i3prev.push_back(i2); 284 | 285 | EXPECT_EQ(i0.next(), i0next); 286 | EXPECT_EQ(i1.next(), i1next); 287 | EXPECT_EQ(i2.next(), i2next); 288 | EXPECT_EQ(i3.next(), i3next); 289 | EXPECT_EQ(i0.prev(), i0prev); 290 | EXPECT_EQ(i1.prev(), i1prev); 291 | EXPECT_EQ(i2.prev(), i2prev); 292 | EXPECT_EQ(i3.prev(), i3prev); 293 | 294 | i2.unlink(i3); 295 | 296 | EXPECT_EQ(i0.next(), i0next); 297 | EXPECT_EQ(i1.next(), i1next); 298 | EXPECT_EQ(i2.next(), empty); 299 | EXPECT_EQ(i3.next(), i3next); 300 | EXPECT_EQ(i0.prev(), i0prev); 301 | EXPECT_EQ(i1.prev(), i1prev); 302 | EXPECT_EQ(i2.prev(), i2prev); 303 | EXPECT_EQ(i3.prev(), empty); 304 | 305 | i0.unlink(i3); 306 | 307 | EXPECT_EQ(i0.next(), i0next); 308 | EXPECT_EQ(i1.next(), i1next); 309 | EXPECT_EQ(i2.next(), empty); 310 | EXPECT_EQ(i3.next(), i3next); 311 | EXPECT_EQ(i0.prev(), i0prev); 312 | EXPECT_EQ(i1.prev(), i1prev); 313 | EXPECT_EQ(i2.prev(), i2prev); 314 | EXPECT_EQ(i3.prev(), empty); 315 | 316 | i0.unlink(i1); 317 | 318 | EXPECT_EQ(i0.next(), empty); 319 | EXPECT_EQ(i1.next(), i1next); 320 | EXPECT_EQ(i2.next(), empty); 321 | EXPECT_EQ(i3.next(), i3next); 322 | EXPECT_EQ(i0.prev(), i0prev); 323 | EXPECT_EQ(i1.prev(), empty); 324 | EXPECT_EQ(i2.prev(), i2prev); 325 | EXPECT_EQ(i3.prev(), empty); 326 | 327 | i0.unlink(i1); 328 | 329 | EXPECT_EQ(i0.next(), empty); 330 | EXPECT_EQ(i1.next(), i1next); 331 | EXPECT_EQ(i2.next(), empty); 332 | EXPECT_EQ(i3.next(), i3next); 333 | EXPECT_EQ(i0.prev(), i0prev); 334 | EXPECT_EQ(i1.prev(), empty); 335 | EXPECT_EQ(i2.prev(), i2prev); 336 | EXPECT_EQ(i3.prev(), empty); 337 | 338 | i1.unlink(i2); 339 | 340 | EXPECT_EQ(i0.next(), empty); 341 | EXPECT_EQ(i1.next(), empty); 342 | EXPECT_EQ(i2.next(), empty); 343 | EXPECT_EQ(i3.next(), i3next); 344 | EXPECT_EQ(i0.prev(), i0prev); 345 | EXPECT_EQ(i1.prev(), empty); 346 | EXPECT_EQ(i2.prev(), empty); 347 | EXPECT_EQ(i3.prev(), empty); 348 | 349 | i0.unlink(i3); 350 | 351 | EXPECT_EQ(i0.next(), empty); 352 | EXPECT_EQ(i1.next(), empty); 353 | EXPECT_EQ(i2.next(), empty); 354 | EXPECT_EQ(i3.next(), i3next); 355 | EXPECT_EQ(i0.prev(), i0prev); 356 | EXPECT_EQ(i1.prev(), empty); 357 | EXPECT_EQ(i2.prev(), empty); 358 | EXPECT_EQ(i3.prev(), empty); 359 | 360 | i3.unlink(i0); 361 | 362 | EXPECT_EQ(i0.next(), empty); 363 | EXPECT_EQ(i1.next(), empty); 364 | EXPECT_EQ(i2.next(), empty); 365 | EXPECT_EQ(i3.next(), empty); 366 | EXPECT_EQ(i0.prev(), empty); 367 | EXPECT_EQ(i1.prev(), empty); 368 | EXPECT_EQ(i2.prev(), empty); 369 | EXPECT_EQ(i3.prev(), empty); 370 | } 371 | -------------------------------------------------------------------------------- /test/graph_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(graph, constructor) 8 | { 9 | graph g; 10 | EXPECT_EQ(g.left.right, &g.right); 11 | EXPECT_EQ(g.right.left, &g.left); 12 | } 13 | 14 | TEST(graph, insert) 15 | { 16 | graph g; 17 | 18 | g.insert(5); 19 | g.insert(10); 20 | g.insert(3); 21 | g.insert(6); 22 | 23 | graph::iterator i = g.begin(); 24 | EXPECT_FALSE((i == g.end())); 25 | if (i != g.end()) 26 | { 27 | EXPECT_EQ(*i, 5); 28 | } 29 | i++; 30 | EXPECT_FALSE((i == g.end())); 31 | if (i != g.end()) 32 | { 33 | EXPECT_EQ(*i, 10); 34 | } 35 | i++; 36 | EXPECT_FALSE((i == g.end())); 37 | if (i != g.end()) 38 | { 39 | EXPECT_EQ(*i, 3); 40 | } 41 | i++; 42 | EXPECT_FALSE((i == g.end())); 43 | if (i != g.end()) 44 | { 45 | EXPECT_EQ(*i, 6); 46 | } 47 | i++; 48 | EXPECT_TRUE((i == g.end())); 49 | } 50 | 51 | TEST(graph, clear) 52 | { 53 | graph g; 54 | 55 | g.insert(5); 56 | g.insert(10); 57 | g.insert(3); 58 | g.insert(6); 59 | 60 | graph::iterator i = g.begin(); 61 | EXPECT_FALSE((i == g.end())); 62 | if (i != g.end()) 63 | { 64 | EXPECT_EQ(*i, 5); 65 | } 66 | i++; 67 | EXPECT_FALSE((i == g.end())); 68 | if (i != g.end()) 69 | { 70 | EXPECT_EQ(*i, 10); 71 | } 72 | i++; 73 | EXPECT_FALSE((i == g.end())); 74 | if (i != g.end()) 75 | { 76 | EXPECT_EQ(*i, 3); 77 | } 78 | i++; 79 | EXPECT_FALSE((i == g.end())); 80 | if (i != g.end()) 81 | { 82 | EXPECT_EQ(*i, 6); 83 | } 84 | i++; 85 | EXPECT_TRUE((i == g.end())); 86 | 87 | g.clear(); 88 | EXPECT_TRUE((g.begin() == g.end())); 89 | } 90 | 91 | TEST(graph_iterator, copy_constructor) 92 | { 93 | graph g; 94 | 95 | graph::iterator i0 = g.insert(5); 96 | graph::iterator i1 = g.insert(10); 97 | graph::iterator i2 = g.insert(3); 98 | graph::iterator i3 = g.insert(6); 99 | 100 | i0.link(i1); 101 | i1.link(i2); 102 | i2.link(i3); 103 | i3.link(i0); 104 | 105 | array::iterator> empty; 106 | 107 | array::iterator> i0next; 108 | i0next.push_back(i1); 109 | 110 | array::iterator> i1next; 111 | i1next.push_back(i2); 112 | 113 | array::iterator> i2next; 114 | i2next.push_back(i3); 115 | 116 | array::iterator> i3next; 117 | i3next.push_back(i0); 118 | 119 | array::iterator> i0prev; 120 | i0prev.push_back(i3); 121 | 122 | array::iterator> i1prev; 123 | i1prev.push_back(i0); 124 | 125 | array::iterator> i2prev; 126 | i2prev.push_back(i1); 127 | 128 | array::iterator> i3prev; 129 | i3prev.push_back(i2); 130 | 131 | EXPECT_EQ(i0.next(), i0next); 132 | EXPECT_EQ(i1.next(), i1next); 133 | EXPECT_EQ(i2.next(), i2next); 134 | EXPECT_EQ(i3.next(), i3next); 135 | EXPECT_EQ(i0.prev(), i0prev); 136 | EXPECT_EQ(i1.prev(), i1prev); 137 | EXPECT_EQ(i2.prev(), i2prev); 138 | EXPECT_EQ(i3.prev(), i3prev); 139 | 140 | graph g2 = g; 141 | 142 | graph::iterator i = g2.begin(); 143 | EXPECT_EQ(*i, 5); 144 | i++; 145 | EXPECT_EQ(*i, 10); 146 | i++; 147 | EXPECT_EQ(*i, 3); 148 | i++; 149 | EXPECT_EQ(*i, 6); 150 | 151 | i = g2.begin(); 152 | 153 | EXPECT_EQ(*i, 5); 154 | EXPECT_EQ(i.next().size(), 1); 155 | i = i.next()[0]; 156 | EXPECT_EQ(*i, 10); 157 | EXPECT_EQ(i.next().size(), 1); 158 | i = i.next()[0]; 159 | EXPECT_EQ(*i, 3); 160 | EXPECT_EQ(i.next().size(), 1); 161 | i = i.next()[0]; 162 | EXPECT_EQ(*i, 6); 163 | EXPECT_EQ(i.next().size(), 1); 164 | i = i.next()[0]; 165 | EXPECT_EQ(*i, 5); 166 | 167 | i = g2.begin(); 168 | 169 | EXPECT_EQ(*i, 5); 170 | EXPECT_EQ(i.prev().size(), 1); 171 | i = i.prev()[0]; 172 | EXPECT_EQ(*i, 6); 173 | EXPECT_EQ(i.prev().size(), 1); 174 | i = i.prev()[0]; 175 | EXPECT_EQ(*i, 3); 176 | EXPECT_EQ(i.prev().size(), 1); 177 | i = i.prev()[0]; 178 | EXPECT_EQ(*i, 10); 179 | EXPECT_EQ(i.prev().size(), 1); 180 | i = i.prev()[0]; 181 | EXPECT_EQ(*i, 5); 182 | } 183 | 184 | TEST(graph_iterator, assign) 185 | { 186 | graph g; 187 | 188 | graph::iterator i0 = g.insert(5); 189 | graph::iterator i1 = g.insert(10); 190 | graph::iterator i2 = g.insert(3); 191 | graph::iterator i3 = g.insert(6); 192 | 193 | i0.link(i1); 194 | i1.link(i2); 195 | i2.link(i3); 196 | i3.link(i0); 197 | 198 | array::iterator> empty; 199 | 200 | array::iterator> i0next; 201 | i0next.push_back(i1); 202 | 203 | array::iterator> i1next; 204 | i1next.push_back(i2); 205 | 206 | array::iterator> i2next; 207 | i2next.push_back(i3); 208 | 209 | array::iterator> i3next; 210 | i3next.push_back(i0); 211 | 212 | array::iterator> i0prev; 213 | i0prev.push_back(i3); 214 | 215 | array::iterator> i1prev; 216 | i1prev.push_back(i0); 217 | 218 | array::iterator> i2prev; 219 | i2prev.push_back(i1); 220 | 221 | array::iterator> i3prev; 222 | i3prev.push_back(i2); 223 | 224 | EXPECT_EQ(i0.next(), i0next); 225 | EXPECT_EQ(i1.next(), i1next); 226 | EXPECT_EQ(i2.next(), i2next); 227 | EXPECT_EQ(i3.next(), i3next); 228 | EXPECT_EQ(i0.prev(), i0prev); 229 | EXPECT_EQ(i1.prev(), i1prev); 230 | EXPECT_EQ(i2.prev(), i2prev); 231 | EXPECT_EQ(i3.prev(), i3prev); 232 | 233 | graph g2; 234 | 235 | g2.insert(5); 236 | g2.insert(4); 237 | 238 | EXPECT_EQ(*g2.begin(), 5); 239 | EXPECT_EQ(*g2.rbegin(), 4); 240 | 241 | g2 = g; 242 | 243 | graph::iterator i = g2.begin(); 244 | EXPECT_EQ(*i, 5); 245 | i++; 246 | EXPECT_EQ(*i, 10); 247 | i++; 248 | EXPECT_EQ(*i, 3); 249 | i++; 250 | EXPECT_EQ(*i, 6); 251 | 252 | i = g2.begin(); 253 | 254 | EXPECT_EQ(*i, 5); 255 | EXPECT_EQ(i.next().size(), 1); 256 | i = i.next()[0]; 257 | EXPECT_EQ(*i, 10); 258 | EXPECT_EQ(i.next().size(), 1); 259 | i = i.next()[0]; 260 | EXPECT_EQ(*i, 3); 261 | EXPECT_EQ(i.next().size(), 1); 262 | i = i.next()[0]; 263 | EXPECT_EQ(*i, 6); 264 | EXPECT_EQ(i.next().size(), 1); 265 | i = i.next()[0]; 266 | EXPECT_EQ(*i, 5); 267 | 268 | i = g2.begin(); 269 | 270 | EXPECT_EQ(*i, 5); 271 | EXPECT_EQ(i.prev().size(), 1); 272 | i = i.prev()[0]; 273 | EXPECT_EQ(*i, 6); 274 | EXPECT_EQ(i.prev().size(), 1); 275 | i = i.prev()[0]; 276 | EXPECT_EQ(*i, 3); 277 | EXPECT_EQ(i.prev().size(), 1); 278 | i = i.prev()[0]; 279 | EXPECT_EQ(*i, 10); 280 | EXPECT_EQ(i.prev().size(), 1); 281 | i = i.prev()[0]; 282 | EXPECT_EQ(*i, 5); 283 | } 284 | 285 | -------------------------------------------------------------------------------- /test/hash_map_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(hash_map, constructor) 10 | { 11 | srand(5); 12 | uint32_t val = rand(); 13 | srand(5); 14 | hash_map h; 15 | EXPECT_EQ(h.size(), 0); 16 | EXPECT_EQ(h.buckets.size(), 17); 17 | EXPECT_EQ(h.salt, val); 18 | EXPECT_EQ(h.shift, 28); 19 | } 20 | 21 | TEST(hash_map, insert) 22 | { 23 | srand(0); 24 | 25 | hash_map h; 26 | array counts(fill(101, 0)); 27 | EXPECT_EQ(h.size(), 0); 28 | EXPECT_EQ(h.buckets.size(), 17); 29 | 30 | for (int i = 0; i < 1000; i++) 31 | { 32 | int value = rand()%101 - 50; 33 | int value2 = value+1; 34 | counts[value+50]++; 35 | h.insert_duplicate(value, value2); 36 | EXPECT_EQ(h.size(), i+1); 37 | EXPECT_GE(h.buckets.size(), h.size()); 38 | for (int j = 0; j < 101; j++) 39 | EXPECT_EQ(count_all(h, j-50), counts[j]); 40 | } 41 | } 42 | 43 | TEST(hash_map, find) 44 | { 45 | srand(0); 46 | 47 | hash_map h; 48 | array counts(fill(101, 0)); 49 | EXPECT_EQ(h.size(), 0); 50 | EXPECT_EQ(h.buckets.size(), 17); 51 | 52 | for (int i = 0; i < 100; i++) 53 | { 54 | int value = rand()%101 - 50; 55 | int value2 = value+1; 56 | counts[value+50]++; 57 | h.insert_duplicate(value, value2); 58 | EXPECT_EQ(h.size(), i+1); 59 | EXPECT_GE(h.buckets.size(), h.size()); 60 | for (int j = 0; j < 101; j++) 61 | EXPECT_EQ(count_all(h, j-50), counts[j]); 62 | } 63 | 64 | for (int i = 0; i < counts.size(); i++) 65 | { 66 | hash_map::iterator result = h.find(i-50); 67 | if (counts[i] > 0) 68 | { 69 | EXPECT_FALSE((result == h.end())); 70 | if (result != h.end()) 71 | { 72 | EXPECT_EQ(result->key, i-50); 73 | EXPECT_EQ(result->value, i-49); 74 | } 75 | } 76 | else 77 | EXPECT_TRUE((result == h.end())); 78 | } 79 | } 80 | 81 | TEST(hash_map, contains) 82 | { 83 | srand(0); 84 | 85 | hash_map h; 86 | array counts(fill(101, 0)); 87 | EXPECT_EQ(h.size(), 0); 88 | EXPECT_EQ(h.buckets.size(), 17); 89 | 90 | for (int i = 0; i < 100; i++) 91 | { 92 | int value = rand()%101 - 50; 93 | int value2 = value+1; 94 | counts[value+50]++; 95 | h.insert_duplicate(value, value2); 96 | EXPECT_EQ(h.size(), i+1); 97 | EXPECT_GE(h.buckets.size(), h.size()); 98 | for (int j = 0; j < 101; j++) 99 | EXPECT_EQ(count_all(h, j-50), counts[j]); 100 | } 101 | 102 | for (int i = 0; i < counts.size(); i++) 103 | { 104 | if (counts[i] > 0) 105 | EXPECT_TRUE(h.contains(i-50)); 106 | else 107 | EXPECT_FALSE(h.contains(i-50)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /test/hash_set_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | using namespace core; 7 | 8 | TEST(hash_set, increment) 9 | { 10 | srand(0); 11 | 12 | hash_set h; 13 | array counts(fill(101, 0)); 14 | EXPECT_EQ(h.size(), 0); 15 | EXPECT_EQ(h.buckets.size(), 17); 16 | 17 | for (int i = 0; i < 1000; i++) 18 | { 19 | int value = rand()%101 - 50; 20 | counts[value+50]++; 21 | h.insert_duplicate(value); 22 | EXPECT_EQ(h.size(), i+1); 23 | EXPECT_GE(h.buckets.size(), h.size()); 24 | for (int j = 0; j < 101; j++) 25 | EXPECT_EQ(count_all(h, j-50), counts[j]); 26 | } 27 | 28 | array countsstar(fill(101, 0)); 29 | array countsget(fill(101, 0)); 30 | array countsptr(fill(101, 0)); 31 | for (hash_set::iterator i = h.begin(); i != h.end(); i++) 32 | { 33 | countsstar[*i+50]++; 34 | countsget[i.get()+50]++; 35 | countsptr[*(i.ptr())+50]++; 36 | } 37 | 38 | EXPECT_EQ(counts, countsstar); 39 | EXPECT_EQ(counts, countsget); 40 | EXPECT_EQ(counts, countsptr); 41 | } 42 | 43 | TEST(hash_set, decrement) 44 | { 45 | srand(0); 46 | 47 | hash_set h; 48 | array counts(fill(101, 0)); 49 | EXPECT_EQ(h.size(), 0); 50 | EXPECT_EQ(h.buckets.size(), 17); 51 | 52 | for (int i = 0; i < 1000; i++) 53 | { 54 | int value = rand()%101 - 50; 55 | counts[value+50]++; 56 | h.insert_duplicate(value); 57 | EXPECT_EQ(h.size(), i+1); 58 | EXPECT_GE(h.buckets.size(), h.size()); 59 | for (int j = 0; j < 101; j++) 60 | EXPECT_EQ(count_all(h, j-50), counts[j]); 61 | } 62 | 63 | array countsstar(fill(101, 0)); 64 | array countsget(fill(101, 0)); 65 | array countsptr(fill(101, 0)); 66 | for (hash_set::iterator i = h.rbegin(); i != h.rend(); i--) 67 | { 68 | countsstar[*i+50]++; 69 | countsget[i.get()+50]++; 70 | countsptr[*(i.ptr())+50]++; 71 | } 72 | 73 | EXPECT_EQ(counts, countsstar); 74 | EXPECT_EQ(counts, countsget); 75 | EXPECT_EQ(counts, countsptr); 76 | } 77 | 78 | TEST(hash_set, at) 79 | { 80 | srand(0); 81 | 82 | hash_set h; 83 | array counts(fill(101, 0)); 84 | EXPECT_EQ(h.size(), 0); 85 | EXPECT_EQ(h.buckets.size(), 17); 86 | 87 | for (int i = 0; i < 1000; i++) 88 | { 89 | int value = rand()%101 - 50; 90 | counts[value+50]++; 91 | h.insert_duplicate(value); 92 | EXPECT_EQ(h.size(), i+1); 93 | EXPECT_GE(h.buckets.size(), h.size()); 94 | for (int j = 0; j < 101; j++) 95 | EXPECT_EQ(count_all(h, j-50), counts[j]); 96 | } 97 | 98 | array counts2(fill(101, 0)); 99 | for (int i = 0; i < h.size(); i++) 100 | { 101 | counts2[*h.at(i)+50]++; 102 | } 103 | 104 | EXPECT_EQ(counts, counts2); 105 | } 106 | 107 | TEST(hash_set, drop_forward) 108 | { 109 | srand(0); 110 | 111 | hash_set h; 112 | array counts(fill(101, 0)); 113 | EXPECT_EQ(h.size(), 0); 114 | EXPECT_EQ(h.buckets.size(), 17); 115 | 116 | for (int i = 0; i < 1000; i++) 117 | { 118 | int value = rand()%101 - 50; 119 | counts[value+50]++; 120 | h.insert_duplicate(value); 121 | EXPECT_EQ(h.size(), i+1); 122 | EXPECT_GE(h.buckets.size(), h.size()); 123 | for (int j = 0; j < 101; j++) 124 | EXPECT_EQ(count_all(h, j-50), counts[j]); 125 | } 126 | 127 | for (int i = 0; i < 20; i++) 128 | { 129 | int loc = rand()%h.size(); 130 | counts[*h.at(loc)+50]--; 131 | h.at(loc).drop(); 132 | } 133 | 134 | array counts2(fill(101, 0)); 135 | for (hash_set::iterator i = h.begin(); i != h.end(); i++) 136 | counts2[*i+50]++; 137 | 138 | EXPECT_EQ(counts, counts2); 139 | } 140 | 141 | TEST(hash_set, drop_backward) 142 | { 143 | srand(0); 144 | 145 | hash_set h; 146 | array counts(fill(101, 0)); 147 | EXPECT_EQ(h.size(), 0); 148 | EXPECT_EQ(h.buckets.size(), 17); 149 | 150 | for (int i = 0; i < 1000; i++) 151 | { 152 | int value = rand()%101 - 50; 153 | counts[value+50]++; 154 | h.insert_duplicate(value); 155 | EXPECT_EQ(h.size(), i+1); 156 | EXPECT_GE(h.buckets.size(), h.size()); 157 | for (int j = 0; j < 101; j++) 158 | EXPECT_EQ(count_all(h, j-50), counts[j]); 159 | } 160 | 161 | for (int i = 0; i < 20; i++) 162 | { 163 | int loc = rand()%h.size(); 164 | counts[*h.at(loc)+50]--; 165 | h.at(loc+1).drop(-1); 166 | } 167 | 168 | array counts2(fill(101, 0)); 169 | for (hash_set::iterator i = h.begin(); i != h.end(); i++) 170 | counts2[*i+50]++; 171 | 172 | EXPECT_EQ(counts, counts2); 173 | } 174 | -------------------------------------------------------------------------------- /test/hash_set_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(hash_set, constructor) 10 | { 11 | srand(5); 12 | uint32_t val = rand(); 13 | srand(5); 14 | hash_set h; 15 | EXPECT_EQ(h.size(), 0); 16 | EXPECT_EQ(h.buckets.size(), 17); 17 | EXPECT_EQ(h.salt, val); 18 | EXPECT_EQ(h.shift, 28); 19 | } 20 | 21 | TEST(hash_set, insert) 22 | { 23 | srand(0); 24 | 25 | hash_set h; 26 | array counts(fill(101, 0)); 27 | EXPECT_EQ(h.size(), 0); 28 | EXPECT_EQ(h.buckets.size(), 17); 29 | 30 | for (int i = 0; i < 1000; i++) 31 | { 32 | int value = rand()%101 - 50; 33 | counts[value+50]++; 34 | h.insert_duplicate(value); 35 | EXPECT_EQ(h.size(), i+1); 36 | EXPECT_GE(h.buckets.size(), h.size()); 37 | for (int j = 0; j < 101; j++) 38 | EXPECT_EQ(count_all(h, j-50), counts[j]); 39 | } 40 | } 41 | 42 | TEST(hash_set, find) 43 | { 44 | srand(0); 45 | 46 | hash_set h; 47 | array counts(fill(101, 0)); 48 | EXPECT_EQ(h.size(), 0); 49 | EXPECT_EQ(h.buckets.size(), 17); 50 | 51 | for (int i = 0; i < 100; i++) 52 | { 53 | int value = rand()%101 - 50; 54 | counts[value+50]++; 55 | h.insert_duplicate(value); 56 | EXPECT_EQ(h.size(), i+1); 57 | EXPECT_GE(h.buckets.size(), h.size()); 58 | for (int j = 0; j < 101; j++) 59 | EXPECT_EQ(count_all(h, j-50), counts[j]); 60 | } 61 | 62 | for (int i = 0; i < counts.size(); i++) 63 | { 64 | hash_set::iterator result = h.find(i-50); 65 | if (counts[i] > 0) 66 | { 67 | EXPECT_FALSE((result == h.end())); 68 | if (result != h.end()) 69 | { 70 | EXPECT_EQ(*result, i-50); 71 | } 72 | } 73 | else 74 | { 75 | EXPECT_TRUE((result == h.end())); 76 | } 77 | } 78 | } 79 | 80 | TEST(hash_set, count_all) 81 | { 82 | srand(0); 83 | 84 | hash_set h; 85 | array counts(fill(101, 0)); 86 | EXPECT_EQ(h.size(), 0); 87 | EXPECT_EQ(h.buckets.size(), 17); 88 | 89 | for (int i = 0; i < 100; i++) 90 | { 91 | int value = rand()%101 - 50; 92 | counts[value+50]++; 93 | h.insert_duplicate(value); 94 | EXPECT_EQ(h.size(), i+1); 95 | EXPECT_GE(h.buckets.size(), h.size()); 96 | for (int j = 0; j < 101; j++) 97 | EXPECT_EQ(count_all(h, j-50), counts[j]); 98 | } 99 | 100 | for (int i = 0; i < counts.size(); i++) 101 | EXPECT_EQ(h.count_all(i-50), counts[i]); 102 | } 103 | 104 | TEST(hash_set, contains) 105 | { 106 | srand(0); 107 | 108 | hash_set h; 109 | array counts(fill(101, 0)); 110 | EXPECT_EQ(h.size(), 0); 111 | EXPECT_EQ(h.buckets.size(), 17); 112 | 113 | for (int i = 0; i < 100; i++) 114 | { 115 | int value = rand()%101 - 50; 116 | counts[value+50]++; 117 | h.insert_duplicate(value); 118 | EXPECT_EQ(h.size(), i+1); 119 | EXPECT_GE(h.buckets.size(), h.size()); 120 | for (int j = 0; j < 101; j++) 121 | EXPECT_EQ(count_all(h, j-50), counts[j]); 122 | } 123 | 124 | for (int i = 0; i < counts.size(); i++) 125 | { 126 | if (counts[i] > 0) 127 | EXPECT_TRUE(h.contains(i-50)); 128 | else 129 | EXPECT_FALSE(h.contains(i-50)); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /test/heap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(heap, heap_make) 10 | { 11 | core::array x = array_t(7, 3, 1, 2, 3, 6, 3, 7); 12 | 13 | heap_make(x); 14 | 15 | EXPECT_EQ(x, array_t(7, 7, 6, 3, 3, 1, 3, 2)); 16 | } 17 | 18 | TEST(heap, heap_pop) 19 | { 20 | core::array x = array_t(7, 7, 6, 3, 3, 1, 3, 2); 21 | 22 | EXPECT_EQ(heap_pop(x), 7); 23 | EXPECT_EQ(heap_pop(x), 6); 24 | EXPECT_EQ(heap_pop(x), 3); 25 | EXPECT_EQ(heap_pop(x), 3); 26 | EXPECT_EQ(heap_pop(x), 3); 27 | EXPECT_EQ(heap_pop(x), 2); 28 | EXPECT_EQ(heap_pop(x), 1); 29 | } 30 | 31 | TEST(heap, heap_push) 32 | { 33 | core::array x; 34 | 35 | heap_push(x, 3); 36 | EXPECT_EQ(x, array_t(1, 3)); 37 | heap_push(x, 1); 38 | EXPECT_EQ(x, array_t(2, 3, 1)); 39 | heap_push(x, 2); 40 | EXPECT_EQ(x, array_t(3, 3, 1, 2)); 41 | heap_push(x, 3); 42 | EXPECT_EQ(x, array_t(4, 3, 3, 2, 1)); 43 | heap_push(x, 6); 44 | EXPECT_EQ(x, array_t(5, 6, 3, 2, 1, 3)); 45 | heap_push(x, 3); 46 | EXPECT_EQ(x, array_t(6, 6, 3, 3, 1, 3, 2)); 47 | heap_push(x, 7); 48 | EXPECT_EQ(x, array_t(7, 7, 3, 6, 1, 3, 2, 3)); 49 | } 50 | 51 | TEST(heap, sort_heap_inplace) 52 | { 53 | core::array x = array_t(7, 3, 1, 2, 3, 6, 3, 7); 54 | 55 | sort_heap_inplace(x); 56 | 57 | EXPECT_EQ(x, array_t(7, 1, 2, 3, 3, 3, 6, 7)); 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /test/implier.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(implier, compare) 8 | { 9 | EXPECT_FALSE((implier(5, 10) < implier(2, 16))); 10 | EXPECT_FALSE((implier(5, 16) < implier(2, 10))); 11 | EXPECT_TRUE ((implier(2, 10) < implier(5, 16))); 12 | EXPECT_TRUE ((implier(2, 16) < implier(5, 10))); 13 | EXPECT_FALSE((implier(5, 16) < implier(2, 16))); 14 | EXPECT_FALSE((implier(2, 16) < implier(2, 10))); 15 | EXPECT_TRUE ((implier(2, 16) < implier(5, 16))); 16 | EXPECT_FALSE((implier(2, 16) < implier(2, 10))); 17 | 18 | EXPECT_TRUE ((implier(5, 10) > implier(2, 16))); 19 | EXPECT_TRUE ((implier(5, 16) > implier(2, 10))); 20 | EXPECT_FALSE((implier(2, 10) > implier(5, 16))); 21 | EXPECT_FALSE((implier(2, 16) > implier(5, 10))); 22 | EXPECT_TRUE ((implier(5, 16) > implier(2, 16))); 23 | EXPECT_FALSE((implier(2, 16) > implier(2, 10))); 24 | EXPECT_FALSE((implier(2, 16) > implier(5, 16))); 25 | EXPECT_FALSE((implier(2, 16) > implier(2, 10))); 26 | 27 | EXPECT_FALSE((implier(5, 10) <= implier(2, 16))); 28 | EXPECT_FALSE((implier(5, 16) <= implier(2, 10))); 29 | EXPECT_TRUE ((implier(2, 10) <= implier(5, 16))); 30 | EXPECT_TRUE ((implier(2, 16) <= implier(5, 10))); 31 | EXPECT_FALSE((implier(5, 16) <= implier(2, 16))); 32 | EXPECT_TRUE ((implier(2, 16) <= implier(2, 10))); 33 | EXPECT_TRUE ((implier(2, 16) <= implier(5, 16))); 34 | EXPECT_TRUE ((implier(2, 16) <= implier(2, 10))); 35 | 36 | EXPECT_TRUE ((implier(5, 10) >= implier(2, 16))); 37 | EXPECT_TRUE ((implier(5, 16) >= implier(2, 10))); 38 | EXPECT_FALSE((implier(2, 10) >= implier(5, 16))); 39 | EXPECT_FALSE((implier(2, 16) >= implier(5, 10))); 40 | EXPECT_TRUE ((implier(5, 16) >= implier(2, 16))); 41 | EXPECT_TRUE ((implier(2, 16) >= implier(2, 10))); 42 | EXPECT_FALSE((implier(2, 16) >= implier(5, 16))); 43 | EXPECT_TRUE ((implier(2, 16) >= implier(2, 10))); 44 | 45 | EXPECT_FALSE((implier(5, 10) == implier(2, 16))); 46 | EXPECT_FALSE((implier(5, 16) == implier(2, 10))); 47 | EXPECT_FALSE((implier(2, 10) == implier(5, 16))); 48 | EXPECT_FALSE((implier(2, 16) == implier(5, 10))); 49 | EXPECT_FALSE((implier(5, 16) == implier(2, 16))); 50 | EXPECT_TRUE ((implier(2, 16) == implier(2, 10))); 51 | EXPECT_FALSE((implier(2, 16) == implier(5, 16))); 52 | EXPECT_TRUE ((implier(2, 16) == implier(2, 10))); 53 | 54 | EXPECT_TRUE ((implier(5, 10) != implier(2, 16))); 55 | EXPECT_TRUE ((implier(5, 16) != implier(2, 10))); 56 | EXPECT_TRUE ((implier(2, 10) != implier(5, 16))); 57 | EXPECT_TRUE ((implier(2, 16) != implier(5, 10))); 58 | EXPECT_TRUE ((implier(5, 16) != implier(2, 16))); 59 | EXPECT_FALSE((implier(2, 16) != implier(2, 10))); 60 | EXPECT_TRUE ((implier(2, 16) != implier(5, 16))); 61 | EXPECT_FALSE((implier(2, 16) != implier(2, 10))); 62 | } 63 | -------------------------------------------------------------------------------- /test/index_list_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(index_list_iterator, iterate) 10 | { 11 | index_list x = range(0, 10); 12 | 13 | int j = 0; 14 | for (index_list::iterator i = x.begin(); i != x.end(); i++) 15 | { 16 | EXPECT_EQ(j, *i); 17 | j++; 18 | } 19 | EXPECT_EQ(10, j); 20 | } 21 | 22 | TEST(index_list_iterator, index) 23 | { 24 | index_list x = index_list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 25 | 26 | EXPECT_EQ(5, *x.at(0)); 27 | EXPECT_EQ(3, *x.at(2)); 28 | EXPECT_EQ(7, *x.at(-1)); 29 | EXPECT_EQ(2, *x.at(-3)); 30 | 31 | EXPECT_EQ(5, x.at(0).get()); 32 | EXPECT_EQ(3, x.at(2).get()); 33 | EXPECT_EQ(7, x.at(-1).get()); 34 | EXPECT_EQ(2, x.at(-3).get()); 35 | 36 | EXPECT_EQ(5, *x.at(0).ptr()); 37 | EXPECT_EQ(3, *x.at(2).ptr()); 38 | EXPECT_EQ(7, *x.at(-1).ptr()); 39 | EXPECT_EQ(2, *x.at(-3).ptr()); 40 | 41 | EXPECT_EQ(0, x.at(0).idx()); 42 | EXPECT_EQ(2, x.at(2).idx()); 43 | EXPECT_EQ(x.size()-1, x.at(-1).idx()); 44 | EXPECT_EQ(x.size()-3, x.at(-3).idx()); 45 | 46 | x.at(2).get() = 5; 47 | x.at(-3).get() = 9; 48 | 49 | EXPECT_EQ(5, *x.at(2)); 50 | EXPECT_EQ(9, *x.at(-3)); 51 | } 52 | 53 | TEST(index_list_iterator, sub) 54 | { 55 | index_list x = range(0, 10); 56 | EXPECT_EQ(x.at(4).sub(3), range(4, 7)); 57 | EXPECT_EQ(x.at(7).sub(-3), range(4, 7)); 58 | EXPECT_EQ(x.at(4).sub(), range(4, 10)); 59 | EXPECT_EQ(x.at(4).subcpy(3), range(4, 7)); 60 | EXPECT_EQ(x.at(7).subcpy(-3), range(4, 7)); 61 | EXPECT_EQ(x.at(4).subcpy(), range(4, 10)); 62 | 63 | const index_list y = range(0, 10); 64 | EXPECT_EQ(y.at(4).sub(3), range(4, 7)); 65 | EXPECT_EQ(y.at(7).sub(-3), range(4, 7)); 66 | EXPECT_EQ(x.at(4).sub(), range(4, 10)); 67 | EXPECT_EQ(y.at(4).subcpy(3), range(4, 7)); 68 | EXPECT_EQ(y.at(7).subcpy(-3), range(4, 7)); 69 | EXPECT_EQ(x.at(4).subcpy(), range(4, 10)); 70 | } 71 | 72 | TEST(index_list_iterator, drop) 73 | { 74 | index_list x = range(0, 10); 75 | 76 | index_list::iterator i = x.at(0); 77 | i.drop(1); 78 | EXPECT_EQ(9, x.size()); 79 | EXPECT_EQ(x, range(1, 10)); 80 | EXPECT_EQ(i.idx(), 0); 81 | 82 | i = x.at(2); 83 | i.drop(-2); 84 | EXPECT_EQ(7, x.size()); 85 | EXPECT_EQ(x, range(3, 10)); 86 | EXPECT_EQ(i.idx(), 0); 87 | 88 | i = x.at(4); 89 | i.drop(-2); 90 | EXPECT_EQ(5, x.size()); 91 | EXPECT_EQ(x, index_list_t(5, 3, 4, 7, 8, 9)); 92 | EXPECT_EQ(i.idx(), 2); 93 | 94 | i = x.at(2); 95 | i.drop(2); 96 | EXPECT_EQ(3, x.size()); 97 | EXPECT_EQ(x, index_list_t(3, 3, 4, 9)); 98 | EXPECT_EQ(i.idx(), 2); 99 | 100 | i = x.at(2); 101 | i.drop(1); 102 | EXPECT_EQ(2, x.size()); 103 | EXPECT_EQ(x, index_list_t(2, 3, 4)); 104 | EXPECT_EQ(i.idx(), 2); 105 | } 106 | 107 | TEST(index_list_iterator, pop) 108 | { 109 | index_list x = range(0, 10); 110 | index_list y; 111 | 112 | index_list::iterator i = x.at(0); 113 | y = i.pop(1); 114 | EXPECT_EQ(9, x.size()); 115 | EXPECT_EQ(x, range(1, 10)); 116 | EXPECT_EQ(1, y.size()); 117 | EXPECT_EQ(0, y[0]); 118 | EXPECT_EQ(i.idx(), 0); 119 | 120 | i = x.at(2); 121 | y = i.pop(-2); 122 | EXPECT_EQ(7, x.size()); 123 | EXPECT_EQ(x, range(3, 10)); 124 | 125 | EXPECT_EQ(2, y.size()); 126 | EXPECT_EQ(y, range(1, 3)); 127 | EXPECT_EQ(i.idx(), 0); 128 | 129 | i = x.at(4); 130 | y = i.pop(-2); 131 | EXPECT_EQ(5, x.size()); 132 | EXPECT_EQ(x, index_list_t(5, 3, 4, 7, 8, 9)); 133 | 134 | EXPECT_EQ(2, y.size()); 135 | EXPECT_EQ(y, range(5, 7)); 136 | EXPECT_EQ(i.idx(), 2); 137 | 138 | i = x.at(2); 139 | y = i.pop(2); 140 | EXPECT_EQ(3, x.size()); 141 | EXPECT_EQ(x, index_list_t(3, 3, 4, 9)); 142 | 143 | EXPECT_EQ(2, y.size()); 144 | EXPECT_EQ(y, index_list_t(2, 7, 8)); 145 | EXPECT_EQ(i.idx(), 2); 146 | 147 | i = x.at(2); 148 | y = i.pop(1); 149 | EXPECT_EQ(2, x.size()); 150 | EXPECT_EQ(x, range(3, 5)); 151 | 152 | EXPECT_EQ(1, y.size()); 153 | EXPECT_EQ(y[0], 9); 154 | EXPECT_EQ(i.idx(), 2); 155 | } 156 | 157 | TEST(index_list_iterator, push) 158 | { 159 | index_list x = range(0, 10); 160 | 161 | // We can't use operator<< here because that uses 162 | // the push function and we can't use the push function 163 | // to test the push function :/ 164 | index_list::iterator i = x.at(0); 165 | i.push(5); 166 | EXPECT_EQ(11, x.size()); 167 | EXPECT_EQ(x[0], 5); 168 | EXPECT_EQ(x.sub(1, 11), range(0, 10)); 169 | EXPECT_EQ(i.idx(), 1); 170 | 171 | i = x.at(5); 172 | i.push(3); 173 | EXPECT_EQ(12, x.size()); 174 | EXPECT_EQ(x[0], 5); 175 | EXPECT_EQ(x.sub(1, 5), range(0, 4)); 176 | EXPECT_EQ(x[5], 3); 177 | EXPECT_EQ(x.sub(6, 12), range(4, 10)); 178 | EXPECT_EQ(i.idx(), 6); 179 | 180 | i = x.at(12); 181 | i.push(8); 182 | EXPECT_EQ(13, x.size()); 183 | EXPECT_EQ(x[0], 5); 184 | EXPECT_EQ(x.sub(1, 5), range(0, 4)); 185 | EXPECT_EQ(x[5], 3); 186 | EXPECT_EQ(x.sub(6, 12), range(4, 10)); 187 | EXPECT_EQ(x[12], 8); 188 | EXPECT_EQ(i.idx(), 13); 189 | } 190 | 191 | TEST(index_list_iterator, append) 192 | { 193 | index_list x = range(0, 10); 194 | index_list y = range(0, 4); 195 | 196 | // We can't use operator<< here because that uses 197 | // the append function and we can't use the append function 198 | // to test the append function :/ 199 | index_list::iterator i = x.begin(); 200 | i.append(y); 201 | EXPECT_EQ(14, x.size()); 202 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 203 | EXPECT_EQ(x.sub(4, 14), range(0, 10)); 204 | EXPECT_EQ(i.idx(), 4); 205 | 206 | i = x.at(7); 207 | i.append(y); 208 | EXPECT_EQ(18, x.size()); 209 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 210 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 211 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 212 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 213 | EXPECT_EQ(i.idx(), 11); 214 | 215 | i = x.end(); 216 | i.append(y); 217 | EXPECT_EQ(22, x.size()); 218 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 219 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 220 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 221 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 222 | EXPECT_EQ(x.sub(18, 22), range(0, 4)); 223 | EXPECT_EQ(i.idx(), x.size()); 224 | 225 | x = range(0, 10); 226 | 227 | i = x.begin(); 228 | i.append(y.sub()); 229 | EXPECT_EQ(14, x.size()); 230 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 231 | EXPECT_EQ(x.sub(4, 14), range(0, 10)); 232 | EXPECT_EQ(i.idx(), 4); 233 | 234 | i = x.at(7); 235 | i.append(y.sub()); 236 | EXPECT_EQ(18, x.size()); 237 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 238 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 239 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 240 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 241 | EXPECT_EQ(i.idx(), 11); 242 | 243 | i = x.end(); 244 | i.append(y.sub()); 245 | EXPECT_EQ(22, x.size()); 246 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 247 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 248 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 249 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 250 | EXPECT_EQ(x.sub(18, 22), range(0, 4)); 251 | EXPECT_EQ(i.idx(), x.size()); 252 | } 253 | 254 | TEST(index_list_iterator, replace) 255 | { 256 | index_list x = range(0, 10); 257 | index_list y = range(0, 10); 258 | 259 | index_list::iterator i = x.at(4); 260 | i.replace(3, 5); 261 | EXPECT_EQ(8, x.size()); 262 | EXPECT_EQ(x, index_list() 263 | + range(0, 4) 264 | + 5 265 | + range(7, 10)); 266 | EXPECT_EQ(i.idx(), 5); 267 | 268 | i = x.at(4); 269 | i.replace(3, 3); 270 | EXPECT_EQ(6, x.size()); 271 | EXPECT_EQ(x, index_list() 272 | + range(0, 4) 273 | + 3 274 | + range(9, 10)); 275 | EXPECT_EQ(i.idx(), 5); 276 | 277 | i = x.at(4); 278 | i.replace(1, 8); 279 | EXPECT_EQ(6, x.size()); 280 | EXPECT_EQ(x, index_list() 281 | + range(0, 4) 282 | + 8 283 | + range(9, 10)); 284 | EXPECT_EQ(i.idx(), 5); 285 | 286 | i = x.at(4); 287 | i.replace(-1, 9); 288 | EXPECT_EQ(6, x.size()); 289 | EXPECT_EQ(x, index_list() 290 | + range(0, 3) 291 | + 9 292 | + 8 293 | + range(9, 10)); 294 | EXPECT_EQ(i.idx(), 4); 295 | 296 | i = x.at(4); 297 | i.replace(-1, 6); 298 | EXPECT_EQ(6, x.size()); 299 | EXPECT_EQ(x, index_list() 300 | + range(0, 3) 301 | + 6 302 | + 8 303 | + range(9, 10)); 304 | EXPECT_EQ(i.idx(), 4); 305 | 306 | i = x.at(4); 307 | i.replace(-4, 2); 308 | EXPECT_EQ(3, x.size()); 309 | EXPECT_EQ(x, index_list() 310 | + 2 311 | + 8 312 | + range(9, 10)); 313 | EXPECT_EQ(i.idx(), 1); 314 | } 315 | 316 | TEST(index_list_iterator, replace_container) 317 | { 318 | index_list x = range(0, 10); 319 | index_list y = range(0, 10); 320 | 321 | index_list::iterator i = x.at(4); 322 | i.replace(3, y.sub(0, 3)); 323 | EXPECT_EQ(10, x.size()); 324 | EXPECT_EQ(x, index_list() 325 | + range(0, 4) 326 | + y.sub(0, 3) 327 | + range(7, 10)); 328 | EXPECT_EQ(i.idx(), 7); 329 | 330 | i = x.at(4); 331 | i.replace(3, y.sub(0, 1)); 332 | EXPECT_EQ(8, x.size()); 333 | EXPECT_EQ(x, index_list() 334 | + range(0, 4) 335 | + y[0] 336 | + range(7, 10)); 337 | EXPECT_EQ(i.idx(), 5); 338 | 339 | i = x.at(4); 340 | i.replace(1, y.sub(0, 3)); 341 | EXPECT_EQ(10, x.size()); 342 | EXPECT_EQ(x, index_list() 343 | + range(0, 4) 344 | + y.sub(0, 3) 345 | + range(7, 10)); 346 | EXPECT_EQ(i.idx(), 7); 347 | 348 | i = x.at(4); 349 | i.replace(-1, y.sub(0, 6)); 350 | EXPECT_EQ(15, x.size()); 351 | EXPECT_EQ(x, index_list() 352 | + range(0, 3) 353 | + y.sub(0, 6) 354 | + y.sub(0, 3) 355 | + range(7, 10)); 356 | EXPECT_EQ(i.idx(), 9); 357 | 358 | i = x.at(4); 359 | i.replace(-1, y.sub(0, 2)); 360 | EXPECT_EQ(16, x.size()); 361 | EXPECT_EQ(x, index_list() 362 | + range(0, 3) 363 | + y.sub(0, 2) 364 | + y.sub(1, 6) 365 | + y.sub(0, 3) 366 | + range(7, 10)); 367 | EXPECT_EQ(i.idx(), 5); 368 | 369 | i = x.at(4); 370 | i.replace(-1, y.sub(0, 6)); 371 | EXPECT_EQ(21, x.size()); 372 | EXPECT_EQ(x, index_list() 373 | + range(0, 3) 374 | + y.sub(0, 6) 375 | + y.sub(1, 2) 376 | + y.sub(1, 6) 377 | + y.sub(0, 3) 378 | + range(7, 10)); 379 | EXPECT_EQ(i.idx(), 9); 380 | 381 | i = x.at(4); 382 | i.replace(-4, y.sub(0, 2)); 383 | EXPECT_EQ(19, x.size()); 384 | EXPECT_EQ(x, index_list() 385 | + y.sub(0, 2) 386 | + y.sub(1, 6) 387 | + y.sub(1, 2) 388 | + y.sub(1, 6) 389 | + y.sub(0, 3) 390 | + range(7, 10)); 391 | EXPECT_EQ(i.idx(), 2); 392 | 393 | i = x.at(4); 394 | i.replace(-4, fill(4, 10)); 395 | EXPECT_EQ(19, x.size()); 396 | EXPECT_EQ(x, index_list() 397 | + fill(4, 10) 398 | + y.sub(3, 6) 399 | + y.sub(1, 2) 400 | + y.sub(1, 6) 401 | + y.sub(0, 3) 402 | + range(7, 10)); 403 | EXPECT_EQ(i.idx(), 4); 404 | } 405 | 406 | TEST(index_list_iterator, swap) 407 | { 408 | index_list x = range(0, 10); 409 | 410 | x.at(5).swap(x.at(2)); 411 | EXPECT_EQ(5, x[2]); 412 | EXPECT_EQ(2, x[5]); 413 | 414 | x.begin().swap(x.rbegin()); 415 | EXPECT_EQ(9, x[0]); 416 | EXPECT_EQ(0, x[9]); 417 | } 418 | -------------------------------------------------------------------------------- /test/index_list_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(index_list_struct, base_constructor) 10 | { 11 | index_list x; 12 | EXPECT_EQ(x.size(), 0); 13 | EXPECT_EQ(x.left.prev, &x.left); 14 | EXPECT_EQ(x.left.next, &x.right); 15 | EXPECT_EQ(x.right.prev, &x.left); 16 | EXPECT_EQ(x.right.next, &x.right); 17 | } 18 | 19 | TEST(index_list_struct, copy_constructor) 20 | { 21 | index_list x(index_list_t(5, 1, 9, 7, 2, 5)); 22 | EXPECT_EQ(x, index_list_t(5, 1, 9, 7, 2, 5)); 23 | } 24 | 25 | TEST(index_list_struct, fill_constructor) 26 | { 27 | index_list x = fill(20, 10); 28 | EXPECT_EQ(20, x.size()); 29 | for (int i = 0; i < x.size(); i++) 30 | EXPECT_EQ(x[i], 10); 31 | } 32 | 33 | TEST(index_list_struct, sparse_range_constructor) 34 | { 35 | index_list x = sparse_range(0, 10); 36 | EXPECT_EQ(10, x.size()); 37 | for (int i = 0; i < x.size(); i++) 38 | EXPECT_EQ(x[i], i); 39 | 40 | x = sparse_range(10, 0, -1); 41 | EXPECT_EQ(10, x.size()); 42 | for (int i = 0; i < x.size(); i++) 43 | EXPECT_EQ(x[i], 10-i); 44 | 45 | x = sparse_range(0, 10, 2); 46 | EXPECT_EQ(5, x.size()); 47 | for (int i = 0; i < x.size(); i++) 48 | EXPECT_EQ(x[i], i*2); 49 | 50 | x = sparse_range(10, 0, -2); 51 | EXPECT_EQ(5, x.size()); 52 | for (int i = 0; i < x.size(); i++) 53 | EXPECT_EQ(x[i], 10-i*2); 54 | } 55 | 56 | TEST(index_list_struct, value_constructor) 57 | { 58 | index_list x = index_list_t(5, 1, 3, 5, 7, 9); 59 | EXPECT_EQ(5, x.size()); 60 | for (int i = 0; i < x.size(); i++) 61 | EXPECT_EQ(x[i], i*2+1); 62 | } 63 | 64 | TEST(index_list_struct, index) 65 | { 66 | index_list x = index_list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 67 | EXPECT_EQ(8, x.size()); 68 | 69 | EXPECT_EQ(5, *x.at(0)); 70 | EXPECT_EQ(3, *x.at(2)); 71 | EXPECT_EQ(7, *x.at(-1)); 72 | EXPECT_EQ(2, *x.at(-3)); 73 | 74 | EXPECT_EQ(5, x.get(0)); 75 | EXPECT_EQ(3, x.get(2)); 76 | EXPECT_EQ(7, x.get(-1)); 77 | EXPECT_EQ(2, x.get(-3)); 78 | 79 | EXPECT_EQ(5, *x.ptr(0)); 80 | EXPECT_EQ(3, *x.ptr(2)); 81 | EXPECT_EQ(7, *x.ptr(-1)); 82 | EXPECT_EQ(2, *x.ptr(-3)); 83 | 84 | EXPECT_EQ(5, x[0]); 85 | EXPECT_EQ(3, x[2]); 86 | EXPECT_EQ(7, x[-1]); 87 | EXPECT_EQ(2, x[-3]); 88 | 89 | EXPECT_EQ(5, x.front()); 90 | EXPECT_EQ(7, x.back()); 91 | 92 | EXPECT_EQ(5, *x.begin()); 93 | EXPECT_EQ(7, *x.rbegin()); 94 | } 95 | 96 | TEST(index_list_struct, sub) 97 | { 98 | index_list x = index_list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 99 | index_list y = index_list_t(4, 3, 5, 6, 2); 100 | index_list z = index_list_t(4, 6, 2, 1, 7); 101 | 102 | // positive start and end 103 | EXPECT_EQ(y, x.sub(2, 6)); 104 | EXPECT_EQ(y, x.subcpy(2, 6)); 105 | 106 | // positive start, negative end 107 | EXPECT_EQ(y, x.sub(2, -2)); 108 | EXPECT_EQ(y, x.subcpy(2, -2)); 109 | 110 | // negative start and end 111 | EXPECT_EQ(y, x.sub(-6, -2)); 112 | EXPECT_EQ(y, x.subcpy(-6, -2)); 113 | 114 | // negative start, positive end 115 | EXPECT_EQ(y, x.sub(-6, 6)); 116 | EXPECT_EQ(y, x.subcpy(-6, 6)); 117 | 118 | // single input 119 | EXPECT_EQ(z, x.sub(4)); 120 | EXPECT_EQ(z, x.sub(-4)); 121 | EXPECT_EQ(z, x.subcpy(4)); 122 | EXPECT_EQ(z, x.subcpy(-4)); 123 | 124 | // no inputs 125 | EXPECT_EQ(x, x.sub()); 126 | EXPECT_EQ(y, y.sub()); 127 | EXPECT_EQ(z, z.sub()); 128 | } 129 | 130 | TEST(index_list_struct, drop) 131 | { 132 | index_list x = sparse_range(0, 10); 133 | x.drop_back(5); 134 | EXPECT_EQ(sparse_range(0, 5), x); 135 | 136 | x = sparse_range(0, 10); 137 | x.drop_front(5); 138 | EXPECT_EQ(sparse_range(5, 10), x); 139 | 140 | x = sparse_range(0, 10); 141 | x.drop(3, 8); 142 | EXPECT_EQ(x, index_list() 143 | + sparse_range(0, 3) 144 | + sparse_range(8, 10)); 145 | 146 | x = sparse_range(0, 10); 147 | x.drop(-7, -2); 148 | EXPECT_EQ(x, index_list() 149 | + sparse_range(0, 3) 150 | + sparse_range(8, 10)); 151 | } 152 | 153 | TEST(index_list_struct, pop) 154 | { 155 | index_list x = sparse_range(0, 10); 156 | index_list y = x.pop_back(5); 157 | EXPECT_EQ(sparse_range(0, 5), x); 158 | EXPECT_EQ(sparse_range(5, 10), y); 159 | 160 | x = sparse_range(0, 10); 161 | y = x.pop_front(5); 162 | EXPECT_EQ(sparse_range(5, 10), x); 163 | EXPECT_EQ(sparse_range(0, 5), y); 164 | 165 | x = sparse_range(0, 10); 166 | y = x.pop(3, 8); 167 | EXPECT_EQ(x, index_list() 168 | + sparse_range(0, 3) 169 | + sparse_range(8, 10)); 170 | EXPECT_EQ(y, sparse_range(3, 8)); 171 | 172 | x = sparse_range(0, 10); 173 | y = x.pop(-7, -2); 174 | EXPECT_EQ(x, index_list() 175 | + sparse_range(0, 3) 176 | + sparse_range(8, 10)); 177 | EXPECT_EQ(y, sparse_range(3, 8)); 178 | } 179 | 180 | TEST(index_list_struct, push_back) 181 | { 182 | index_list x; 183 | EXPECT_EQ(0, x.size()); 184 | for (int i = 0; i < 10; i++) 185 | { 186 | x.push_back(i); 187 | EXPECT_EQ(i+1, x.size()); 188 | } 189 | 190 | x.push_back(20); 191 | EXPECT_EQ(11, x.size()); 192 | EXPECT_EQ(x.sub(0, 10), sparse_range(0, 10)); 193 | EXPECT_EQ(x[10], 20); 194 | } 195 | 196 | TEST(index_list_struct, push_front) 197 | { 198 | index_list x; 199 | EXPECT_EQ(0, x.size()); 200 | for (int i = 0; i < 10; i++) 201 | { 202 | x.push_front(9 - i); 203 | EXPECT_EQ(i+1, x.size()); 204 | } 205 | 206 | EXPECT_EQ(sparse_range(0, 10), x); 207 | } 208 | 209 | TEST(index_list_struct, append_back) 210 | { 211 | index_list x = fill(1, 8); 212 | index_list y = fill(1, 3); 213 | index_list z; 214 | EXPECT_EQ(1, x.size()); 215 | EXPECT_EQ(1, y.size()); 216 | 217 | z = x; 218 | x.append_back(y); 219 | EXPECT_EQ(z.size() + y.size(), x.size()); 220 | EXPECT_EQ(z, x.sub(0, z.size())); 221 | EXPECT_EQ(y, x.sub(z.size(), z.size()+y.size())); 222 | 223 | z = y; 224 | y.append_back(x); 225 | EXPECT_EQ(z.size() + x.size(), y.size()); 226 | EXPECT_EQ(z, y.sub(0, z.size())); 227 | EXPECT_EQ(x, y.sub(z.size(), z.size()+x.size())); 228 | 229 | z = x; 230 | x.append_back(y); 231 | EXPECT_EQ(z.size()+y.size(), x.size()); 232 | EXPECT_EQ(z, x.sub(0, z.size())); 233 | EXPECT_EQ(y, x.sub(z.size(), z.size()+y.size())); 234 | 235 | z = x; 236 | x.append_back(index_list()); 237 | EXPECT_EQ(z, x); 238 | } 239 | 240 | TEST(index_list_struct, append_front) 241 | { 242 | index_list x = fill(1, 8); 243 | index_list y = fill(1, 3); 244 | index_list z; 245 | EXPECT_EQ(1, x.size()); 246 | EXPECT_EQ(1, y.size()); 247 | 248 | z = x; 249 | x.append_front(y); 250 | EXPECT_EQ(z.size()+y.size(), x.size()); 251 | EXPECT_EQ(y, x.sub(0, y.size())); 252 | EXPECT_EQ(z, x.sub(y.size(), y.size()+z.size())); 253 | 254 | z = y; 255 | y.append_front(x); 256 | EXPECT_EQ(3, y.size()); 257 | EXPECT_EQ(x, y.sub(0, x.size())); 258 | EXPECT_EQ(z, y.sub(x.size(), x.size()+z.size())); 259 | 260 | z = x; 261 | x.append_front(y); 262 | EXPECT_EQ(z.size()+y.size(), x.size()); 263 | EXPECT_EQ(y, x.sub(0, y.size())); 264 | EXPECT_EQ(z, x.sub(y.size(), y.size()+z.size())); 265 | 266 | z = x; 267 | x.append_front(index_list()); 268 | EXPECT_EQ(z, x); 269 | } 270 | 271 | TEST(index_list_struct, replace) 272 | { 273 | index_list x = sparse_range(0, 10); 274 | EXPECT_EQ(x, sparse_range(0, 10)); 275 | 276 | x.replace(0, 3, 5); 277 | EXPECT_EQ(x, index_list() 278 | + 5 279 | + sparse_range(3, 10)); 280 | 281 | x = sparse_range(0, 10); 282 | x.replace(7, 10, 5); 283 | EXPECT_EQ(x, index_list() 284 | + sparse_range(0, 7) 285 | + 5); 286 | 287 | x = sparse_range(0, 10); 288 | x.replace(3, 7, 5); 289 | EXPECT_EQ(x, index_list() 290 | + sparse_range(0, 3) 291 | + 5 292 | + sparse_range(7, 10)); 293 | 294 | x = sparse_range(0, 10); 295 | x.replace(-7, -3, 5); 296 | EXPECT_EQ(x, index_list() 297 | + sparse_range(0, 3) 298 | + 5 299 | + sparse_range(7, 10)); 300 | 301 | x = sparse_range(0, 10); 302 | x.replace(-7, 7, 5); 303 | EXPECT_EQ(x, index_list() 304 | + sparse_range(0, 3) 305 | + 5 306 | + sparse_range(7, 10)); 307 | 308 | x = sparse_range(0, 10); 309 | x.replace(3, -3, 5); 310 | EXPECT_EQ(x, index_list() 311 | + sparse_range(0, 3) 312 | + 5 313 | + sparse_range(7, 10)); 314 | 315 | x = sparse_range(0, 10); 316 | x.replace_front(3, 5); 317 | EXPECT_EQ(x, index_list() 318 | + 5 319 | + sparse_range(3, 10)); 320 | 321 | x = sparse_range(0, 10); 322 | x.replace_back(3, 5); 323 | EXPECT_EQ(x, index_list() 324 | + sparse_range(0, 7) 325 | + 5); 326 | } 327 | 328 | TEST(index_list_struct, replace_container) 329 | { 330 | index_list x = sparse_range(0, 10); 331 | EXPECT_EQ(x, sparse_range(0, 10)); 332 | index_list y = index_list_t(5, 2, 5, 3, 7, 2); 333 | 334 | x.replace(0, 3, y); 335 | EXPECT_EQ(x, index_list() 336 | + y 337 | + sparse_range(3, 10)); 338 | 339 | x = sparse_range(0, 10); 340 | x.replace(7, 10, y); 341 | EXPECT_EQ(x, index_list() 342 | + sparse_range(0, 7) 343 | + y); 344 | 345 | x = sparse_range(0, 10); 346 | x.replace(3, 7, y); 347 | EXPECT_EQ(x, index_list() 348 | + sparse_range(0, 3) 349 | + y 350 | + sparse_range(7, 10)); 351 | 352 | x = sparse_range(0, 10); 353 | x.replace(-7, -3, y); 354 | EXPECT_EQ(x, index_list() 355 | + sparse_range(0, 3) 356 | + y 357 | + sparse_range(7, 10)); 358 | 359 | x = sparse_range(0, 10); 360 | x.replace(-7, 7, y); 361 | EXPECT_EQ(x, index_list() 362 | + sparse_range(0, 3) 363 | + y 364 | + sparse_range(7, 10)); 365 | 366 | x = sparse_range(0, 10); 367 | x.replace(3, -3, y); 368 | EXPECT_EQ(x, index_list() 369 | + sparse_range(0, 3) 370 | + y 371 | + sparse_range(7, 10)); 372 | 373 | x = sparse_range(0, 10); 374 | x.replace_front(3, y); 375 | EXPECT_EQ(x, index_list() 376 | + y 377 | + sparse_range(3, 10)); 378 | 379 | x = sparse_range(0, 10); 380 | x.replace_back(3, y); 381 | EXPECT_EQ(x, index_list() 382 | + sparse_range(0, 7) 383 | + y); 384 | } 385 | 386 | TEST(index_list_struct, swap) 387 | { 388 | index_list x = sparse_range(0, 10); 389 | index_list y = fill(8, 5); 390 | EXPECT_EQ(sparse_range(0, 10), x); 391 | EXPECT_EQ(fill(8, 5), y); 392 | x.swap(y); 393 | EXPECT_EQ(sparse_range(0, 10), y); 394 | EXPECT_EQ(fill(8, 5), x); 395 | } 396 | 397 | TEST(index_list_struct, resize) 398 | { 399 | index_list x; 400 | x.resize(20, 10); 401 | EXPECT_EQ(fill(20, 10), x); 402 | 403 | x.resize(10, 5); 404 | EXPECT_EQ(fill(10, 10), x); 405 | } 406 | 407 | TEST(index_list_struct, clear) 408 | { 409 | index_list x = sparse_range(0, 10); 410 | EXPECT_EQ(10, x.size()); 411 | 412 | x.clear(); 413 | EXPECT_EQ(0, x.size()); 414 | } 415 | 416 | TEST(index_list_struct, release) 417 | { 418 | index_list x = sparse_range(0, 10); 419 | EXPECT_EQ(10, x.size()); 420 | 421 | x.release(); 422 | EXPECT_EQ(0, x.size()); 423 | } 424 | 425 | TEST(index_list_struct, assign) 426 | { 427 | index_list x = sparse_range(0, 10); 428 | EXPECT_EQ(10, x.size()); 429 | 430 | index_list y, z; 431 | 432 | y = x; 433 | z = x.sub(); 434 | EXPECT_EQ(y, x); 435 | EXPECT_EQ(z, x); 436 | EXPECT_EQ(y, z); 437 | } 438 | 439 | TEST(index_list_struct, compare) 440 | { 441 | index_list x = sparse_range(0, 10); 442 | index_list y = sparse_range(10, 0, -1); 443 | 444 | EXPECT_TRUE(x < y); 445 | EXPECT_FALSE(x > y); 446 | EXPECT_TRUE(x <= y); 447 | EXPECT_FALSE(x >= y); 448 | EXPECT_FALSE(x == y); 449 | EXPECT_TRUE(x != y); 450 | 451 | x.clear(); 452 | y.clear(); 453 | 454 | x = sparse_range(0, 5); 455 | y = sparse_range(0, 10); 456 | 457 | EXPECT_TRUE(x < y); 458 | EXPECT_FALSE(x > y); 459 | EXPECT_TRUE(x <= y); 460 | EXPECT_FALSE(x >= y); 461 | EXPECT_FALSE(x == y); 462 | EXPECT_TRUE(x != y); 463 | 464 | x = y; 465 | 466 | EXPECT_FALSE(x < y); 467 | EXPECT_FALSE(x > y); 468 | EXPECT_TRUE(x <= y); 469 | EXPECT_TRUE(x >= y); 470 | EXPECT_TRUE(x == y); 471 | EXPECT_FALSE(x != y); 472 | 473 | x.clear(); 474 | y.clear(); 475 | 476 | for (int i = 0; i < 5; i++) 477 | x.push_back(i); 478 | for (int i = 0; i < 10; i++) 479 | { 480 | y.push_back(i); 481 | x.push_back(10+i); 482 | } 483 | 484 | EXPECT_FALSE(x < y); 485 | EXPECT_TRUE(x > y); 486 | EXPECT_FALSE(x <= y); 487 | EXPECT_TRUE(x >= y); 488 | EXPECT_FALSE(x == y); 489 | EXPECT_TRUE(x != y); 490 | } 491 | -------------------------------------------------------------------------------- /test/list_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(list_iterator, iterate) 10 | { 11 | list x = range(0, 10); 12 | 13 | int j = 0; 14 | for (list::iterator i = x.begin(); i != x.end(); i++) 15 | { 16 | EXPECT_EQ(j, *i); 17 | j++; 18 | } 19 | EXPECT_EQ(10, j); 20 | } 21 | 22 | TEST(list_iterator, index) 23 | { 24 | list x = list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 25 | 26 | EXPECT_EQ(5, *x.at(0)); 27 | EXPECT_EQ(3, *x.at(2)); 28 | EXPECT_EQ(7, *x.at(-1)); 29 | EXPECT_EQ(2, *x.at(-3)); 30 | 31 | EXPECT_EQ(5, x.at(0).get()); 32 | EXPECT_EQ(3, x.at(2).get()); 33 | EXPECT_EQ(7, x.at(-1).get()); 34 | EXPECT_EQ(2, x.at(-3).get()); 35 | 36 | EXPECT_EQ(5, *x.at(0).ptr()); 37 | EXPECT_EQ(3, *x.at(2).ptr()); 38 | EXPECT_EQ(7, *x.at(-1).ptr()); 39 | EXPECT_EQ(2, *x.at(-3).ptr()); 40 | 41 | EXPECT_EQ(0, x.at(0).idx()); 42 | EXPECT_EQ(2, x.at(2).idx()); 43 | EXPECT_EQ(x.size()-1, x.at(-1).idx()); 44 | EXPECT_EQ(x.size()-3, x.at(-3).idx()); 45 | 46 | x.at(2).get() = 5; 47 | x.at(-3).get() = 9; 48 | 49 | EXPECT_EQ(5, *x.at(2)); 50 | EXPECT_EQ(9, *x.at(-3)); 51 | } 52 | 53 | TEST(list_iterator, sub) 54 | { 55 | list x = range(0, 10); 56 | EXPECT_EQ(x.at(4).sub(3), range(4, 7)); 57 | EXPECT_EQ(x.at(7).sub(-3), range(4, 7)); 58 | EXPECT_EQ(x.at(4).sub(), range(4, 10)); 59 | EXPECT_EQ(x.at(4).subcpy(3), range(4, 7)); 60 | EXPECT_EQ(x.at(7).subcpy(-3), range(4, 7)); 61 | EXPECT_EQ(x.at(4).subcpy(), range(4, 10)); 62 | 63 | const list y = range(0, 10); 64 | EXPECT_EQ(y.at(4).sub(3), range(4, 7)); 65 | EXPECT_EQ(y.at(7).sub(-3), range(4, 7)); 66 | EXPECT_EQ(x.at(4).sub(), range(4, 10)); 67 | EXPECT_EQ(y.at(4).subcpy(3), range(4, 7)); 68 | EXPECT_EQ(y.at(7).subcpy(-3), range(4, 7)); 69 | EXPECT_EQ(x.at(4).subcpy(), range(4, 10)); 70 | } 71 | 72 | TEST(list_iterator, drop) 73 | { 74 | list x = range(0, 10); 75 | 76 | list::iterator i = x.at(0); 77 | i.drop(1); 78 | EXPECT_EQ(9, x.size()); 79 | EXPECT_EQ(x, range(1, 10)); 80 | EXPECT_EQ(i.idx(), 0); 81 | 82 | i = x.at(2); 83 | i.drop(-2); 84 | EXPECT_EQ(7, x.size()); 85 | EXPECT_EQ(x, range(3, 10)); 86 | EXPECT_EQ(i.idx(), 0); 87 | 88 | i = x.at(4); 89 | i.drop(-2); 90 | EXPECT_EQ(5, x.size()); 91 | EXPECT_EQ(x, list_t(5, 3, 4, 7, 8, 9)); 92 | EXPECT_EQ(i.idx(), 2); 93 | 94 | i = x.at(2); 95 | i.drop(2); 96 | EXPECT_EQ(3, x.size()); 97 | EXPECT_EQ(x, list_t(3, 3, 4, 9)); 98 | EXPECT_EQ(i.idx(), 2); 99 | 100 | i = x.at(2); 101 | i.drop(1); 102 | EXPECT_EQ(2, x.size()); 103 | EXPECT_EQ(x, list_t(2, 3, 4)); 104 | EXPECT_EQ(i.idx(), 2); 105 | } 106 | 107 | TEST(list_iterator, pop) 108 | { 109 | list x = range(0, 10); 110 | list y; 111 | 112 | list::iterator i = x.at(0); 113 | y = i.pop(1); 114 | EXPECT_EQ(9, x.size()); 115 | EXPECT_EQ(x, range(1, 10)); 116 | EXPECT_EQ(1, y.size()); 117 | EXPECT_EQ(0, y[0]); 118 | EXPECT_EQ(i.idx(), 0); 119 | 120 | i = x.at(2); 121 | y = i.pop(-2); 122 | EXPECT_EQ(7, x.size()); 123 | EXPECT_EQ(x, range(3, 10)); 124 | 125 | EXPECT_EQ(2, y.size()); 126 | EXPECT_EQ(y, range(1, 3)); 127 | EXPECT_EQ(i.idx(), 0); 128 | 129 | i = x.at(4); 130 | y = i.pop(-2); 131 | EXPECT_EQ(5, x.size()); 132 | EXPECT_EQ(x, list_t(5, 3, 4, 7, 8, 9)); 133 | 134 | EXPECT_EQ(2, y.size()); 135 | EXPECT_EQ(y, range(5, 7)); 136 | EXPECT_EQ(i.idx(), 2); 137 | 138 | i = x.at(2); 139 | y = i.pop(2); 140 | EXPECT_EQ(3, x.size()); 141 | EXPECT_EQ(x, list_t(3, 3, 4, 9)); 142 | 143 | EXPECT_EQ(2, y.size()); 144 | EXPECT_EQ(y, list_t(2, 7, 8)); 145 | EXPECT_EQ(i.idx(), 2); 146 | 147 | i = x.at(2); 148 | y = i.pop(1); 149 | EXPECT_EQ(2, x.size()); 150 | EXPECT_EQ(x, range(3, 5)); 151 | 152 | EXPECT_EQ(1, y.size()); 153 | EXPECT_EQ(y[0], 9); 154 | EXPECT_EQ(i.idx(), 2); 155 | } 156 | 157 | TEST(list_iterator, push) 158 | { 159 | list x = range(0, 10); 160 | 161 | // We can't use operator<< here because that uses 162 | // the push function and we can't use the push function 163 | // to test the push function :/ 164 | list::iterator i = x.at(0); 165 | i.push(5); 166 | EXPECT_EQ(11, x.size()); 167 | EXPECT_EQ(x[0], 5); 168 | EXPECT_EQ(x.sub(1, 11), range(0, 10)); 169 | EXPECT_EQ(i.idx(), 1); 170 | 171 | i = x.at(5); 172 | i.push(3); 173 | EXPECT_EQ(12, x.size()); 174 | EXPECT_EQ(x[0], 5); 175 | EXPECT_EQ(x.sub(1, 5), range(0, 4)); 176 | EXPECT_EQ(x[5], 3); 177 | EXPECT_EQ(x.sub(6, 12), range(4, 10)); 178 | EXPECT_EQ(i.idx(), 6); 179 | 180 | i = x.at(12); 181 | i.push(8); 182 | EXPECT_EQ(13, x.size()); 183 | EXPECT_EQ(x[0], 5); 184 | EXPECT_EQ(x.sub(1, 5), range(0, 4)); 185 | EXPECT_EQ(x[5], 3); 186 | EXPECT_EQ(x.sub(6, 12), range(4, 10)); 187 | EXPECT_EQ(x[12], 8); 188 | EXPECT_EQ(i.idx(), 13); 189 | } 190 | 191 | TEST(list_iterator, append) 192 | { 193 | list x = range(0, 10); 194 | list y = range(0, 4); 195 | 196 | // We can't use operator<< here because that uses 197 | // the append function and we can't use the append function 198 | // to test the append function :/ 199 | list::iterator i = x.begin(); 200 | i.append(y); 201 | EXPECT_EQ(14, x.size()); 202 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 203 | EXPECT_EQ(x.sub(4, 14), range(0, 10)); 204 | EXPECT_EQ(i.idx(), 4); 205 | 206 | i = x.at(7); 207 | i.append(y); 208 | EXPECT_EQ(18, x.size()); 209 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 210 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 211 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 212 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 213 | EXPECT_EQ(i.idx(), 11); 214 | 215 | i = x.end(); 216 | i.append(y); 217 | EXPECT_EQ(22, x.size()); 218 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 219 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 220 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 221 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 222 | EXPECT_EQ(x.sub(18, 22), range(0, 4)); 223 | EXPECT_EQ(i.idx(), x.size()); 224 | 225 | x = range(0, 10); 226 | 227 | i = x.begin(); 228 | i.append(y.sub()); 229 | EXPECT_EQ(14, x.size()); 230 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 231 | EXPECT_EQ(x.sub(4, 14), range(0, 10)); 232 | EXPECT_EQ(i.idx(), 4); 233 | 234 | i = x.at(7); 235 | i.append(y.sub()); 236 | EXPECT_EQ(18, x.size()); 237 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 238 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 239 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 240 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 241 | EXPECT_EQ(i.idx(), 11); 242 | 243 | i = x.end(); 244 | i.append(y.sub()); 245 | EXPECT_EQ(22, x.size()); 246 | EXPECT_EQ(x.sub(0, 4), range(0, 4)); 247 | EXPECT_EQ(x.sub(4, 7), range(0, 3)); 248 | EXPECT_EQ(x.sub(7, 11), range(0, 4)); 249 | EXPECT_EQ(x.sub(11, 18), range(3, 10)); 250 | EXPECT_EQ(x.sub(18, 22), range(0, 4)); 251 | EXPECT_EQ(i.idx(), x.size()); 252 | } 253 | 254 | TEST(list_iterator, replace) 255 | { 256 | list x = range(0, 10); 257 | list y = range(0, 10); 258 | 259 | list::iterator i = x.at(4); 260 | i.replace(3, 5); 261 | EXPECT_EQ(8, x.size()); 262 | EXPECT_EQ(x, list() 263 | + range(0, 4) 264 | + 5 265 | + range(7, 10)); 266 | EXPECT_EQ(i.idx(), 5); 267 | 268 | i = x.at(4); 269 | i.replace(3, 3); 270 | EXPECT_EQ(6, x.size()); 271 | EXPECT_EQ(x, list() 272 | + range(0, 4) 273 | + 3 274 | + range(9, 10)); 275 | EXPECT_EQ(i.idx(), 5); 276 | 277 | i = x.at(4); 278 | i.replace(1, 8); 279 | EXPECT_EQ(6, x.size()); 280 | EXPECT_EQ(x, list() 281 | + range(0, 4) 282 | + 8 283 | + range(9, 10)); 284 | EXPECT_EQ(i.idx(), 5); 285 | 286 | i = x.at(4); 287 | i.replace(-1, 9); 288 | EXPECT_EQ(6, x.size()); 289 | EXPECT_EQ(x, list() 290 | + range(0, 3) 291 | + 9 292 | + 8 293 | + range(9, 10)); 294 | EXPECT_EQ(i.idx(), 4); 295 | 296 | i = x.at(4); 297 | i.replace(-1, 6); 298 | EXPECT_EQ(6, x.size()); 299 | EXPECT_EQ(x, list() 300 | + range(0, 3) 301 | + 6 302 | + 8 303 | + range(9, 10)); 304 | EXPECT_EQ(i.idx(), 4); 305 | 306 | i = x.at(4); 307 | i.replace(-4, 2); 308 | EXPECT_EQ(3, x.size()); 309 | EXPECT_EQ(x, list() 310 | + 2 311 | + 8 312 | + range(9, 10)); 313 | EXPECT_EQ(i.idx(), 1); 314 | } 315 | 316 | TEST(list_iterator, replace_container) 317 | { 318 | list x = range(0, 10); 319 | list y = range(0, 10); 320 | 321 | list::iterator i = x.at(4); 322 | i.replace(3, y.sub(0, 3)); 323 | EXPECT_EQ(10, x.size()); 324 | EXPECT_EQ(x, list() 325 | + range(0, 4) 326 | + y.sub(0, 3) 327 | + range(7, 10)); 328 | EXPECT_EQ(i.idx(), 7); 329 | 330 | i = x.at(4); 331 | i.replace(3, y.sub(0, 1)); 332 | EXPECT_EQ(8, x.size()); 333 | EXPECT_EQ(x, list() 334 | + range(0, 4) 335 | + y[0] 336 | + range(7, 10)); 337 | EXPECT_EQ(i.idx(), 5); 338 | 339 | i = x.at(4); 340 | i.replace(1, y.sub(0, 3)); 341 | EXPECT_EQ(10, x.size()); 342 | EXPECT_EQ(x, list() 343 | + range(0, 4) 344 | + y.sub(0, 3) 345 | + range(7, 10)); 346 | EXPECT_EQ(i.idx(), 7); 347 | 348 | i = x.at(4); 349 | i.replace(-1, y.sub(0, 6)); 350 | EXPECT_EQ(15, x.size()); 351 | EXPECT_EQ(x, list() 352 | + range(0, 3) 353 | + y.sub(0, 6) 354 | + y.sub(0, 3) 355 | + range(7, 10)); 356 | EXPECT_EQ(i.idx(), 9); 357 | 358 | i = x.at(4); 359 | i.replace(-1, y.sub(0, 2)); 360 | EXPECT_EQ(16, x.size()); 361 | EXPECT_EQ(x, list() 362 | + range(0, 3) 363 | + y.sub(0, 2) 364 | + y.sub(1, 6) 365 | + y.sub(0, 3) 366 | + range(7, 10)); 367 | EXPECT_EQ(i.idx(), 5); 368 | 369 | i = x.at(4); 370 | i.replace(-1, y.sub(0, 6)); 371 | EXPECT_EQ(21, x.size()); 372 | EXPECT_EQ(x, list() 373 | + range(0, 3) 374 | + y.sub(0, 6) 375 | + y.sub(1, 2) 376 | + y.sub(1, 6) 377 | + y.sub(0, 3) 378 | + range(7, 10)); 379 | EXPECT_EQ(i.idx(), 9); 380 | 381 | i = x.at(4); 382 | i.replace(-4, y.sub(0, 2)); 383 | EXPECT_EQ(19, x.size()); 384 | EXPECT_EQ(x, list() 385 | + y.sub(0, 2) 386 | + y.sub(1, 6) 387 | + y.sub(1, 2) 388 | + y.sub(1, 6) 389 | + y.sub(0, 3) 390 | + range(7, 10)); 391 | EXPECT_EQ(i.idx(), 2); 392 | 393 | i = x.at(4); 394 | i.replace(-4, fill(4, 10)); 395 | EXPECT_EQ(19, x.size()); 396 | EXPECT_EQ(x, list() 397 | + fill(4, 10) 398 | + y.sub(3, 6) 399 | + y.sub(1, 2) 400 | + y.sub(1, 6) 401 | + y.sub(0, 3) 402 | + range(7, 10)); 403 | EXPECT_EQ(i.idx(), 4); 404 | } 405 | 406 | TEST(list_iterator, swap) 407 | { 408 | list x = range(0, 10); 409 | 410 | x.at(5).swap(x.at(2)); 411 | EXPECT_EQ(5, x[2]); 412 | EXPECT_EQ(2, x[5]); 413 | 414 | x.begin().swap(x.rbegin()); 415 | EXPECT_EQ(9, x[0]); 416 | EXPECT_EQ(0, x[9]); 417 | } 418 | -------------------------------------------------------------------------------- /test/list_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace core; 8 | 9 | TEST(list_struct, base_constructor) 10 | { 11 | list x; 12 | EXPECT_EQ(x.size(), 0); 13 | EXPECT_EQ(x.left->prev, x.left); 14 | EXPECT_EQ(x.left->next, x.right); 15 | EXPECT_EQ(x.right->prev, x.left); 16 | EXPECT_EQ(x.right->next, x.right); 17 | } 18 | 19 | TEST(list_struct, copy_constructor) 20 | { 21 | list x(list_t(5, 1, 9, 7, 2, 5)); 22 | EXPECT_EQ(x, list_t(5, 1, 9, 7, 2, 5)); 23 | } 24 | 25 | TEST(list_struct, fill_constructor) 26 | { 27 | list x = fill(20, 10); 28 | EXPECT_EQ(20, x.size()); 29 | for (int i = 0; i < x.size(); i++) 30 | EXPECT_EQ(x[i], 10); 31 | } 32 | 33 | TEST(list_struct, sparse_range_constructor) 34 | { 35 | list x = sparse_range(0, 10); 36 | EXPECT_EQ(10, x.size()); 37 | for (int i = 0; i < x.size(); i++) 38 | EXPECT_EQ(x[i], i); 39 | 40 | x = sparse_range(10, 0, -1); 41 | EXPECT_EQ(10, x.size()); 42 | for (int i = 0; i < x.size(); i++) 43 | EXPECT_EQ(x[i], 10-i); 44 | 45 | x = sparse_range(0, 10, 2); 46 | EXPECT_EQ(5, x.size()); 47 | for (int i = 0; i < x.size(); i++) 48 | EXPECT_EQ(x[i], i*2); 49 | 50 | x = sparse_range(10, 0, -2); 51 | EXPECT_EQ(5, x.size()); 52 | for (int i = 0; i < x.size(); i++) 53 | EXPECT_EQ(x[i], 10-i*2); 54 | } 55 | 56 | TEST(list_struct, value_constructor) 57 | { 58 | list x = list_t(5, 1, 3, 5, 7, 9); 59 | EXPECT_EQ(5, x.size()); 60 | for (int i = 0; i < x.size(); i++) 61 | EXPECT_EQ(x[i], i*2+1); 62 | } 63 | 64 | TEST(list_struct, index) 65 | { 66 | list x = list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 67 | EXPECT_EQ(8, x.size()); 68 | 69 | EXPECT_EQ(5, *x.at(0)); 70 | EXPECT_EQ(3, *x.at(2)); 71 | EXPECT_EQ(7, *x.at(-1)); 72 | EXPECT_EQ(2, *x.at(-3)); 73 | 74 | EXPECT_EQ(5, x.get(0)); 75 | EXPECT_EQ(3, x.get(2)); 76 | EXPECT_EQ(7, x.get(-1)); 77 | EXPECT_EQ(2, x.get(-3)); 78 | 79 | EXPECT_EQ(5, *x.ptr(0)); 80 | EXPECT_EQ(3, *x.ptr(2)); 81 | EXPECT_EQ(7, *x.ptr(-1)); 82 | EXPECT_EQ(2, *x.ptr(-3)); 83 | 84 | EXPECT_EQ(5, x[0]); 85 | EXPECT_EQ(3, x[2]); 86 | EXPECT_EQ(7, x[-1]); 87 | EXPECT_EQ(2, x[-3]); 88 | 89 | EXPECT_EQ(5, x.front()); 90 | EXPECT_EQ(7, x.back()); 91 | 92 | EXPECT_EQ(5, *x.begin()); 93 | EXPECT_EQ(7, *x.rbegin()); 94 | } 95 | 96 | TEST(list_struct, sub) 97 | { 98 | list x = list_t(8, 5, 2, 3, 5, 6, 2, 1, 7); 99 | list y = list_t(4, 3, 5, 6, 2); 100 | list z = list_t(4, 6, 2, 1, 7); 101 | 102 | // positive start and end 103 | EXPECT_EQ(y, x.sub(2, 6)); 104 | EXPECT_EQ(y, x.subcpy(2, 6)); 105 | 106 | // positive start, negative end 107 | EXPECT_EQ(y, x.sub(2, -2)); 108 | EXPECT_EQ(y, x.subcpy(2, -2)); 109 | 110 | // negative start and end 111 | EXPECT_EQ(y, x.sub(-6, -2)); 112 | EXPECT_EQ(y, x.subcpy(-6, -2)); 113 | 114 | // negative start, positive end 115 | EXPECT_EQ(y, x.sub(-6, 6)); 116 | EXPECT_EQ(y, x.subcpy(-6, 6)); 117 | 118 | // single input 119 | EXPECT_EQ(z, x.sub(4)); 120 | EXPECT_EQ(z, x.sub(-4)); 121 | EXPECT_EQ(z, x.subcpy(4)); 122 | EXPECT_EQ(z, x.subcpy(-4)); 123 | 124 | // no inputs 125 | EXPECT_EQ(x, x.sub()); 126 | EXPECT_EQ(y, y.sub()); 127 | EXPECT_EQ(z, z.sub()); 128 | } 129 | 130 | TEST(list_struct, drop) 131 | { 132 | list x = sparse_range(0, 10); 133 | x.drop_back(5); 134 | EXPECT_EQ(sparse_range(0, 5), x); 135 | 136 | x = sparse_range(0, 10); 137 | x.drop_front(5); 138 | EXPECT_EQ(sparse_range(5, 10), x); 139 | 140 | x = sparse_range(0, 10); 141 | x.drop(3, 8); 142 | EXPECT_EQ(x, list() 143 | + sparse_range(0, 3) 144 | + sparse_range(8, 10)); 145 | 146 | x = sparse_range(0, 10); 147 | x.drop(-7, -2); 148 | EXPECT_EQ(x, list() 149 | + sparse_range(0, 3) 150 | + sparse_range(8, 10)); 151 | } 152 | 153 | TEST(list_struct, pop) 154 | { 155 | list x = sparse_range(0, 10); 156 | list y = x.pop_back(5); 157 | EXPECT_EQ(sparse_range(0, 5), x); 158 | EXPECT_EQ(sparse_range(5, 10), y); 159 | 160 | x = sparse_range(0, 10); 161 | y = x.pop_front(5); 162 | EXPECT_EQ(sparse_range(5, 10), x); 163 | EXPECT_EQ(sparse_range(0, 5), y); 164 | 165 | x = sparse_range(0, 10); 166 | y = x.pop(3, 8); 167 | EXPECT_EQ(x, list() 168 | + sparse_range(0, 3) 169 | + sparse_range(8, 10)); 170 | EXPECT_EQ(y, sparse_range(3, 8)); 171 | 172 | x = sparse_range(0, 10); 173 | y = x.pop(-7, -2); 174 | EXPECT_EQ(x, list() 175 | + sparse_range(0, 3) 176 | + sparse_range(8, 10)); 177 | EXPECT_EQ(y, sparse_range(3, 8)); 178 | } 179 | 180 | TEST(list_struct, push_back) 181 | { 182 | list x; 183 | EXPECT_EQ(0, x.size()); 184 | for (int i = 0; i < 10; i++) 185 | { 186 | x.push_back(i); 187 | EXPECT_EQ(i+1, x.size()); 188 | } 189 | 190 | x.push_back(20); 191 | EXPECT_EQ(11, x.size()); 192 | EXPECT_EQ(x.sub(0, 10), sparse_range(0, 10)); 193 | EXPECT_EQ(x[10], 20); 194 | } 195 | 196 | TEST(list_struct, push_front) 197 | { 198 | list x; 199 | EXPECT_EQ(0, x.size()); 200 | for (int i = 0; i < 10; i++) 201 | { 202 | x.push_front(9 - i); 203 | EXPECT_EQ(i+1, x.size()); 204 | } 205 | 206 | EXPECT_EQ(sparse_range(0, 10), x); 207 | } 208 | 209 | TEST(list_struct, append_back) 210 | { 211 | list x = fill(1, 8); 212 | list y = fill(1, 3); 213 | list z; 214 | EXPECT_EQ(1, x.size()); 215 | EXPECT_EQ(1, y.size()); 216 | 217 | z = x; 218 | x.append_back(y); 219 | EXPECT_EQ(z.size() + y.size(), x.size()); 220 | EXPECT_EQ(z, x.sub(0, z.size())); 221 | EXPECT_EQ(y, x.sub(z.size(), z.size()+y.size())); 222 | 223 | z = y; 224 | y.append_back(x); 225 | EXPECT_EQ(z.size() + x.size(), y.size()); 226 | EXPECT_EQ(z, y.sub(0, z.size())); 227 | EXPECT_EQ(x, y.sub(z.size(), z.size()+x.size())); 228 | 229 | z = x; 230 | x.append_back(y); 231 | EXPECT_EQ(z.size()+y.size(), x.size()); 232 | EXPECT_EQ(z, x.sub(0, z.size())); 233 | EXPECT_EQ(y, x.sub(z.size(), z.size()+y.size())); 234 | 235 | z = x; 236 | x.append_back(list()); 237 | EXPECT_EQ(z, x); 238 | } 239 | 240 | TEST(list_struct, append_front) 241 | { 242 | list x = fill(1, 8); 243 | list y = fill(1, 3); 244 | list z; 245 | EXPECT_EQ(1, x.size()); 246 | EXPECT_EQ(1, y.size()); 247 | 248 | z = x; 249 | x.append_front(y); 250 | EXPECT_EQ(z.size()+y.size(), x.size()); 251 | EXPECT_EQ(y, x.sub(0, y.size())); 252 | EXPECT_EQ(z, x.sub(y.size(), y.size()+z.size())); 253 | 254 | z = y; 255 | y.append_front(x); 256 | EXPECT_EQ(3, y.size()); 257 | EXPECT_EQ(x, y.sub(0, x.size())); 258 | EXPECT_EQ(z, y.sub(x.size(), x.size()+z.size())); 259 | 260 | z = x; 261 | x.append_front(y); 262 | EXPECT_EQ(z.size()+y.size(), x.size()); 263 | EXPECT_EQ(y, x.sub(0, y.size())); 264 | EXPECT_EQ(z, x.sub(y.size(), y.size()+z.size())); 265 | 266 | z = x; 267 | x.append_front(list()); 268 | EXPECT_EQ(z, x); 269 | } 270 | 271 | TEST(list_struct, replace) 272 | { 273 | list x = sparse_range(0, 10); 274 | EXPECT_EQ(x, sparse_range(0, 10)); 275 | 276 | x.replace(0, 3, 5); 277 | EXPECT_EQ(x, list() 278 | + 5 279 | + sparse_range(3, 10)); 280 | 281 | x = sparse_range(0, 10); 282 | x.replace(7, 10, 5); 283 | EXPECT_EQ(x, list() 284 | + sparse_range(0, 7) 285 | + 5); 286 | 287 | x = sparse_range(0, 10); 288 | x.replace(3, 7, 5); 289 | EXPECT_EQ(x, list() 290 | + sparse_range(0, 3) 291 | + 5 292 | + sparse_range(7, 10)); 293 | 294 | x = sparse_range(0, 10); 295 | x.replace(-7, -3, 5); 296 | EXPECT_EQ(x, list() 297 | + sparse_range(0, 3) 298 | + 5 299 | + sparse_range(7, 10)); 300 | 301 | x = sparse_range(0, 10); 302 | x.replace(-7, 7, 5); 303 | EXPECT_EQ(x, list() 304 | + sparse_range(0, 3) 305 | + 5 306 | + sparse_range(7, 10)); 307 | 308 | x = sparse_range(0, 10); 309 | x.replace(3, -3, 5); 310 | EXPECT_EQ(x, list() 311 | + sparse_range(0, 3) 312 | + 5 313 | + sparse_range(7, 10)); 314 | 315 | x = sparse_range(0, 10); 316 | x.replace_front(3, 5); 317 | EXPECT_EQ(x, list() 318 | + 5 319 | + sparse_range(3, 10)); 320 | 321 | x = sparse_range(0, 10); 322 | x.replace_back(3, 5); 323 | EXPECT_EQ(x, list() 324 | + sparse_range(0, 7) 325 | + 5); 326 | } 327 | 328 | TEST(list_struct, replace_container) 329 | { 330 | list x = sparse_range(0, 10); 331 | EXPECT_EQ(x, sparse_range(0, 10)); 332 | list y = list_t(5, 2, 5, 3, 7, 2); 333 | 334 | x.replace(0, 3, y); 335 | EXPECT_EQ(x, list() 336 | + y 337 | + sparse_range(3, 10)); 338 | 339 | x = sparse_range(0, 10); 340 | x.replace(7, 10, y); 341 | EXPECT_EQ(x, list() 342 | + sparse_range(0, 7) 343 | + y); 344 | 345 | x = sparse_range(0, 10); 346 | x.replace(3, 7, y); 347 | EXPECT_EQ(x, list() 348 | + sparse_range(0, 3) 349 | + y 350 | + sparse_range(7, 10)); 351 | 352 | x = sparse_range(0, 10); 353 | x.replace(-7, -3, y); 354 | EXPECT_EQ(x, list() 355 | + sparse_range(0, 3) 356 | + y 357 | + sparse_range(7, 10)); 358 | 359 | x = sparse_range(0, 10); 360 | x.replace(-7, 7, y); 361 | EXPECT_EQ(x, list() 362 | + sparse_range(0, 3) 363 | + y 364 | + sparse_range(7, 10)); 365 | 366 | x = sparse_range(0, 10); 367 | x.replace(3, -3, y); 368 | EXPECT_EQ(x, list() 369 | + sparse_range(0, 3) 370 | + y 371 | + sparse_range(7, 10)); 372 | 373 | x = sparse_range(0, 10); 374 | x.replace_front(3, y); 375 | EXPECT_EQ(x, list() 376 | + y 377 | + sparse_range(3, 10)); 378 | 379 | x = sparse_range(0, 10); 380 | x.replace_back(3, y); 381 | EXPECT_EQ(x, list() 382 | + sparse_range(0, 7) 383 | + y); 384 | } 385 | 386 | TEST(list_struct, swap) 387 | { 388 | list x = sparse_range(0, 10); 389 | list y = fill(8, 5); 390 | EXPECT_EQ(sparse_range(0, 10), x); 391 | EXPECT_EQ(fill(8, 5), y); 392 | x.swap(y); 393 | EXPECT_EQ(sparse_range(0, 10), y); 394 | EXPECT_EQ(fill(8, 5), x); 395 | } 396 | 397 | TEST(list_struct, resize) 398 | { 399 | list x; 400 | x.resize(20, 10); 401 | EXPECT_EQ(fill(20, 10), x); 402 | 403 | x.resize(10, 5); 404 | EXPECT_EQ(fill(10, 10), x); 405 | } 406 | 407 | TEST(list_struct, clear) 408 | { 409 | list x = sparse_range(0, 10); 410 | EXPECT_EQ(10, x.size()); 411 | 412 | x.clear(); 413 | EXPECT_EQ(0, x.size()); 414 | } 415 | 416 | TEST(list_struct, release) 417 | { 418 | list x = sparse_range(0, 10); 419 | EXPECT_EQ(10, x.size()); 420 | 421 | x.release(); 422 | EXPECT_EQ(0, x.size()); 423 | } 424 | 425 | TEST(list_struct, assign) 426 | { 427 | list x = sparse_range(0, 10); 428 | EXPECT_EQ(10, x.size()); 429 | 430 | list y, z; 431 | 432 | y = x; 433 | z = x.sub(); 434 | EXPECT_EQ(y, x); 435 | EXPECT_EQ(z, x); 436 | EXPECT_EQ(y, z); 437 | } 438 | 439 | TEST(list_struct, compare) 440 | { 441 | list x = sparse_range(0, 10); 442 | list y = sparse_range(10, 0, -1); 443 | 444 | EXPECT_TRUE(x < y); 445 | EXPECT_FALSE(x > y); 446 | EXPECT_TRUE(x <= y); 447 | EXPECT_FALSE(x >= y); 448 | EXPECT_FALSE(x == y); 449 | EXPECT_TRUE(x != y); 450 | 451 | x.clear(); 452 | y.clear(); 453 | 454 | x = sparse_range(0, 5); 455 | y = sparse_range(0, 10); 456 | 457 | EXPECT_TRUE(x < y); 458 | EXPECT_FALSE(x > y); 459 | EXPECT_TRUE(x <= y); 460 | EXPECT_FALSE(x >= y); 461 | EXPECT_FALSE(x == y); 462 | EXPECT_TRUE(x != y); 463 | 464 | x = y; 465 | 466 | EXPECT_FALSE(x < y); 467 | EXPECT_FALSE(x > y); 468 | EXPECT_TRUE(x <= y); 469 | EXPECT_TRUE(x >= y); 470 | EXPECT_TRUE(x == y); 471 | EXPECT_FALSE(x != y); 472 | 473 | x.clear(); 474 | y.clear(); 475 | 476 | for (int i = 0; i < 5; i++) 477 | x.push_back(i); 478 | for (int i = 0; i < 10; i++) 479 | { 480 | y.push_back(i); 481 | x.push_back(10+i); 482 | } 483 | 484 | EXPECT_FALSE(x < y); 485 | EXPECT_TRUE(x > y); 486 | EXPECT_FALSE(x <= y); 487 | EXPECT_TRUE(x >= y); 488 | EXPECT_FALSE(x == y); 489 | EXPECT_TRUE(x != y); 490 | } 491 | -------------------------------------------------------------------------------- /test/map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | using namespace core; 7 | 8 | TEST(map, insert) 9 | { 10 | map x; 11 | x.insert(1, 10); 12 | EXPECT_EQ(x.size(), 1); 13 | EXPECT_EQ(x.get(0).key, 1); 14 | EXPECT_EQ(x.get(0).value, 10); 15 | 16 | x.insert(5, 7); 17 | EXPECT_EQ(x.size(), 2); 18 | EXPECT_EQ(x.get(0).key, 1); 19 | EXPECT_EQ(x.get(0).value, 10); 20 | EXPECT_EQ(x.get(1).key, 5); 21 | EXPECT_EQ(x.get(1).value, 7); 22 | 23 | x.insert(0, 20); 24 | EXPECT_EQ(x.size(), 3); 25 | EXPECT_EQ(x.get(0).key, 0); 26 | EXPECT_EQ(x.get(0).value, 20); 27 | EXPECT_EQ(x.get(1).key, 1); 28 | EXPECT_EQ(x.get(1).value, 10); 29 | EXPECT_EQ(x.get(2).key, 5); 30 | EXPECT_EQ(x.get(2).value, 7); 31 | 32 | x.insert(3, 5); 33 | EXPECT_EQ(x.size(), 4); 34 | EXPECT_EQ(x.get(0).key, 0); 35 | EXPECT_EQ(x.get(0).value, 20); 36 | EXPECT_EQ(x.get(1).key, 1); 37 | EXPECT_EQ(x.get(1).value, 10); 38 | EXPECT_EQ(x.get(2).key, 3); 39 | EXPECT_EQ(x.get(2).value, 5); 40 | EXPECT_EQ(x.get(3).key, 5); 41 | EXPECT_EQ(x.get(3).value, 7); 42 | 43 | x.clear(); 44 | EXPECT_EQ(x.size(), 0); 45 | 46 | list > y; 47 | srand(0); 48 | for (int i = 0; i < 10; i++) 49 | { 50 | int key = rand(); 51 | int value = rand(); 52 | x.insert(key, value); 53 | y.push_back(implier(key, value)); 54 | } 55 | 56 | sort_quick_inplace(y); 57 | EXPECT_EQ(x.size(), y.size()); 58 | 59 | list >::iterator i = y.begin(); 60 | map::iterator j = x.begin(); 61 | for (; i != y.end() && j != x.end(); i++, j++) 62 | { 63 | EXPECT_EQ(i->key, j->key); 64 | EXPECT_EQ(i->value, j->value); 65 | } 66 | } 67 | 68 | TEST(map, find) 69 | { 70 | map x; 71 | x.insert(1, 10); 72 | x.insert(5, 7); 73 | x.insert(0, 20); 74 | x.insert(3, 5); 75 | EXPECT_EQ(x.find(10), x.end()); 76 | EXPECT_EQ(x.find(2), x.end()); 77 | EXPECT_EQ(x.find(4), x.end()); 78 | EXPECT_EQ(x.find(8), x.end()); 79 | 80 | x.clear(); 81 | srand(0); 82 | for (int i = 0; i < 10; i++) 83 | { 84 | int key = rand(); 85 | int value = rand(); 86 | x.insert(key, value); 87 | } 88 | 89 | map::iterator j = x.begin(); 90 | for (; j != x.end(); j++) 91 | { 92 | EXPECT_EQ(x.find(j->key), j); 93 | } 94 | } 95 | 96 | TEST(map, operator_index) 97 | { 98 | map x; 99 | list > y; 100 | srand(0); 101 | for (int i = 0; i < 10; i++) 102 | { 103 | int key = rand(); 104 | int value = rand(); 105 | x[key] = value; 106 | y.push_back(implier(key, value)); 107 | } 108 | 109 | sort_quick_inplace(y); 110 | EXPECT_EQ(x.size(), y.size()); 111 | 112 | list >::iterator i = y.begin(); 113 | map::iterator j = x.begin(); 114 | for (; i != y.end() && j != x.end(); i++, j++) 115 | { 116 | EXPECT_EQ(i->key, j->key); 117 | EXPECT_EQ(i->value, j->value); 118 | EXPECT_EQ(x[j->key], j->value); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /test/pair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(pair, constructor) 8 | { 9 | pair x(5, 'h'); 10 | EXPECT_EQ(x.first, 5); 11 | EXPECT_EQ(x.second, 'h'); 12 | } 13 | 14 | TEST(pair, compare) 15 | { 16 | pair x(5, 10); 17 | pair y(6, 5); 18 | EXPECT_FALSE((x == y)); 19 | EXPECT_TRUE ((x != y)); 20 | EXPECT_TRUE ((x < y)); 21 | EXPECT_FALSE((x > y)); 22 | EXPECT_TRUE ((x <= y)); 23 | EXPECT_FALSE((x >= y)); 24 | 25 | y.first = 5; 26 | 27 | EXPECT_FALSE((x == y)); 28 | EXPECT_TRUE ((x != y)); 29 | EXPECT_FALSE((x < y)); 30 | EXPECT_TRUE ((x > y)); 31 | EXPECT_FALSE((x <= y)); 32 | EXPECT_TRUE ((x >= y)); 33 | 34 | y.second = 10; 35 | 36 | EXPECT_TRUE ((x == y)); 37 | EXPECT_FALSE((x != y)); 38 | EXPECT_FALSE((x < y)); 39 | EXPECT_FALSE((x > y)); 40 | EXPECT_TRUE ((x <= y)); 41 | EXPECT_TRUE ((x >= y)); 42 | } 43 | -------------------------------------------------------------------------------- /test/range_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(range_iterator, iterate) 8 | { 9 | range x(0, 5); 10 | 11 | int j = 0; 12 | for (range::iterator i = x.begin(); i; i++) 13 | { 14 | EXPECT_EQ(j, *i); 15 | j += 1; 16 | } 17 | EXPECT_EQ(5, j); 18 | } 19 | 20 | TEST(range_iterator, index) 21 | { 22 | range x(0, 10); 23 | 24 | EXPECT_EQ(0, *x.at(0)); 25 | EXPECT_EQ(2, *x.at(2)); 26 | EXPECT_EQ(9, *x.at(-1)); 27 | EXPECT_EQ(7, *x.at(-3)); 28 | 29 | EXPECT_EQ(0, x.at(0).get()); 30 | EXPECT_EQ(2, x.at(2).get()); 31 | EXPECT_EQ(9, x.at(-1).get()); 32 | EXPECT_EQ(7, x.at(-3).get()); 33 | 34 | EXPECT_EQ(0, x.at(0).idx()); 35 | EXPECT_EQ(2, x.at(2).idx()); 36 | EXPECT_EQ(x.size()-1, x.at(-1).idx()); 37 | EXPECT_EQ(x.size()-3, x.at(-3).idx()); 38 | } 39 | 40 | TEST(range_iterator, sub) 41 | { 42 | range x(0, 10); 43 | EXPECT_EQ(x.at(4).sub(3), range(4, 7)); 44 | EXPECT_EQ(x.at(7).sub(-3), range(4, 7)); 45 | EXPECT_EQ(x.at(4).sub(), range(4, 10)); 46 | EXPECT_EQ(x.at(4).subcpy(3), range(4, 7)); 47 | EXPECT_EQ(x.at(7).subcpy(-3), range(4, 7)); 48 | EXPECT_EQ(x.at(4).subcpy(), range(4, 10)); 49 | } 50 | -------------------------------------------------------------------------------- /test/range_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(range_struct, base_constructor) 8 | { 9 | range x(0, 10); 10 | EXPECT_EQ(0, x.start); 11 | EXPECT_EQ(10, x.finish); 12 | } 13 | 14 | TEST(range_struct, copy_constructor) 15 | { 16 | range y(5, 10); 17 | range x(y); 18 | EXPECT_EQ(x, y); 19 | } 20 | 21 | TEST(range_struct, index) 22 | { 23 | range x(0, 8); 24 | EXPECT_EQ(8, x.size()); 25 | 26 | EXPECT_EQ(0, *x.at(0)); 27 | EXPECT_EQ(2, *x.at(2)); 28 | EXPECT_EQ(7, *x.at(-1)); 29 | EXPECT_EQ(5, *x.at(-3)); 30 | 31 | EXPECT_EQ(0, x.get(0)); 32 | EXPECT_EQ(2, x.get(2)); 33 | EXPECT_EQ(7, x.get(-1)); 34 | EXPECT_EQ(5, x.get(-3)); 35 | 36 | EXPECT_EQ(0, x[0]); 37 | EXPECT_EQ(2, x[2]); 38 | EXPECT_EQ(7, x[-1]); 39 | EXPECT_EQ(5, x[-3]); 40 | 41 | EXPECT_EQ(0, x.front()); 42 | EXPECT_EQ(7, x.back()); 43 | 44 | EXPECT_EQ(0, *x.begin()); 45 | EXPECT_EQ(7, *x.rbegin()); 46 | } 47 | 48 | TEST(range_struct, sub) 49 | { 50 | range x(0, 8); 51 | range y(2, 6); 52 | 53 | // positive start and end 54 | EXPECT_EQ(y, x.sub(2, 6)); 55 | EXPECT_EQ(y, x.subcpy(2, 6)); 56 | 57 | // positive start, negative end 58 | EXPECT_EQ(y, x.sub(2, -2)); 59 | EXPECT_EQ(y, x.subcpy(2, -2)); 60 | 61 | // negative start and end 62 | EXPECT_EQ(y, x.sub(-6, -2)); 63 | EXPECT_EQ(y, x.subcpy(-6, -2)); 64 | 65 | // negative start, positive end 66 | EXPECT_EQ(y, x.sub(-6, 6)); 67 | EXPECT_EQ(y, x.subcpy(-6, 6)); 68 | 69 | y = range(4, 8); 70 | // single input 71 | EXPECT_EQ(y, x.sub(4)); 72 | EXPECT_EQ(y, x.sub(-4)); 73 | EXPECT_EQ(y, x.subcpy(4)); 74 | EXPECT_EQ(y, x.subcpy(-4)); 75 | 76 | // ref 77 | EXPECT_EQ(x, x.sub()); 78 | EXPECT_EQ(y, y.sub()); 79 | } 80 | 81 | TEST(range_struct, swap) 82 | { 83 | range x(0, 10); 84 | range y(10, 15); 85 | EXPECT_EQ(range(0, 10), x); 86 | EXPECT_EQ(range(10, 15), y); 87 | x.swap(y); 88 | EXPECT_EQ(range(0, 10), y); 89 | EXPECT_EQ(range(10, 15), x); 90 | } 91 | 92 | TEST(range_struct, compare) 93 | { 94 | range x(0, 10); 95 | range y(10, 0); 96 | 97 | EXPECT_TRUE(x < y); 98 | EXPECT_FALSE(x > y); 99 | EXPECT_TRUE(x <= y); 100 | EXPECT_FALSE(x >= y); 101 | EXPECT_FALSE(x == y); 102 | EXPECT_TRUE(x != y); 103 | 104 | x = range(0, 5); 105 | y = range(0, 10); 106 | 107 | EXPECT_TRUE(x < y); 108 | EXPECT_FALSE(x > y); 109 | EXPECT_TRUE(x <= y); 110 | EXPECT_FALSE(x >= y); 111 | EXPECT_FALSE(x == y); 112 | EXPECT_TRUE(x != y); 113 | 114 | x = y; 115 | 116 | EXPECT_FALSE(x < y); 117 | EXPECT_FALSE(x > y); 118 | EXPECT_TRUE(x <= y); 119 | EXPECT_TRUE(x >= y); 120 | EXPECT_TRUE(x == y); 121 | EXPECT_FALSE(x != y); 122 | } 123 | -------------------------------------------------------------------------------- /test/sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace core; 9 | 10 | TEST(sort, swap) 11 | { 12 | int x = 5; 13 | int y = 10; 14 | 15 | swap(x, y); 16 | 17 | EXPECT_EQ(x, 10); 18 | EXPECT_EQ(y, 5); 19 | } 20 | 21 | TEST(sort, median_iterator) 22 | { 23 | array x = array_t(3, 1, 2, 3); 24 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(1)); 25 | 26 | x = array_t(3, 3, 2, 1); 27 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(1)); 28 | 29 | x = array_t(3, 2, 1, 3); 30 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(0)); 31 | 32 | x = array_t(3, 2, 3, 1); 33 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(0)); 34 | 35 | x = array_t(3, 1, 3, 2); 36 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(2)); 37 | 38 | x = array_t(3, 3, 1, 2); 39 | EXPECT_EQ(median_iterator(x.at(0), x.at(1), x.at(2)), x.at(2)); 40 | } 41 | 42 | TEST(sort, sort_selection) 43 | { 44 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 45 | array y = sort_selection(x); 46 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 47 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1)); 48 | 49 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 50 | y = sort_selection(x); 51 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 52 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 53 | 54 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 55 | y = sort_selection(x); 56 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 57 | EXPECT_EQ(x, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 58 | 59 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 60 | y = sort_selection(x); 61 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 62 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 63 | } 64 | 65 | TEST(sort, sort_selection_inplace) 66 | { 67 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 68 | array y = sort_selection_inplace(x); 69 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 70 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 71 | 72 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 73 | y = sort_selection_inplace(x); 74 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 75 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 76 | 77 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 78 | y = sort_selection_inplace(x); 79 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 80 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 81 | 82 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 83 | y = sort_selection_inplace(x); 84 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 85 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 86 | } 87 | 88 | TEST(sort, sort_quick) 89 | { 90 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 91 | array y = sort_quick(x); 92 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 93 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1)); 94 | 95 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 96 | y = sort_quick(x); 97 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 98 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 99 | 100 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 101 | y = sort_quick(x); 102 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 103 | EXPECT_EQ(x, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 104 | 105 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 106 | y = sort_quick(x); 107 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 108 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 109 | } 110 | 111 | TEST(sort, sort_quick_inplace) 112 | { 113 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 114 | array y = sort_quick_inplace(x); 115 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 116 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 117 | 118 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 119 | y = sort_quick_inplace(x); 120 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 121 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 122 | 123 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 124 | y = sort_quick_inplace(x); 125 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 126 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 127 | 128 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 129 | y = sort_quick_inplace(x); 130 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 131 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 132 | } 133 | 134 | TEST(sort, is_sorted) 135 | { 136 | EXPECT_FALSE(is_sorted(array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1))); 137 | EXPECT_TRUE(is_sorted(array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5))); 138 | EXPECT_FALSE(is_sorted(array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5))); 139 | EXPECT_FALSE(is_sorted(array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1))); 140 | } 141 | 142 | TEST(sort, is_rsorted) 143 | { 144 | EXPECT_FALSE(is_rsorted(array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1))); 145 | EXPECT_FALSE(is_rsorted(array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5))); 146 | EXPECT_FALSE(is_rsorted(array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5))); 147 | EXPECT_TRUE(is_rsorted(array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1))); 148 | } 149 | 150 | TEST(sort, reverse) 151 | { 152 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 153 | array y = reverse(x); 154 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 4, 3, 2, 3, 4, 5, 5)); 155 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1)); 156 | 157 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 158 | y = reverse(x); 159 | EXPECT_EQ(y, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 160 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 161 | 162 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 163 | y = reverse(x); 164 | EXPECT_EQ(y, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 165 | EXPECT_EQ(x, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 166 | 167 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 168 | y = reverse(x); 169 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 170 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 171 | } 172 | 173 | TEST(sort, reverse_inplace) 174 | { 175 | array x = array_t(10, 5, 5, 4, 3, 2, 3, 4, 2, 1, 1); 176 | array y = reverse_inplace(x); 177 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 4, 3, 2, 3, 4, 5, 5)); 178 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 4, 3, 2, 3, 4, 5, 5)); 179 | 180 | x = array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5); 181 | y = reverse_inplace(x); 182 | EXPECT_EQ(y, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 183 | EXPECT_EQ(x, array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1)); 184 | 185 | x = array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5); 186 | y = reverse_inplace(x); 187 | EXPECT_EQ(y, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 188 | EXPECT_EQ(x, array_t(10, 5, 4, 3, 2, 1, 1, 2, 3, 4, 5)); 189 | 190 | x = array_t(10, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1); 191 | y = reverse_inplace(x); 192 | EXPECT_EQ(y, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 193 | EXPECT_EQ(x, array_t(10, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5)); 194 | } 195 | -------------------------------------------------------------------------------- /test/sparse_range_iterator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(sparse_range_iterator, iterate) 8 | { 9 | sparse_range x(0, 10, 2); 10 | 11 | int j = 0; 12 | for (sparse_range::iterator i = x.begin(); i; i++) 13 | { 14 | EXPECT_EQ(j, *i); 15 | j += 2; 16 | } 17 | EXPECT_EQ(10, j); 18 | } 19 | 20 | TEST(sparse_range_iterator, index) 21 | { 22 | sparse_range x(0, 20, 2); 23 | 24 | EXPECT_EQ(0, *x.at(0)); 25 | EXPECT_EQ(4, *x.at(2)); 26 | EXPECT_EQ(18, *x.at(-1)); 27 | EXPECT_EQ(14, *x.at(-3)); 28 | 29 | EXPECT_EQ(0, x.at(0).get()); 30 | EXPECT_EQ(4, x.at(2).get()); 31 | EXPECT_EQ(18, x.at(-1).get()); 32 | EXPECT_EQ(14, x.at(-3).get()); 33 | 34 | EXPECT_EQ(0, x.at(0).idx()); 35 | EXPECT_EQ(2, x.at(2).idx()); 36 | EXPECT_EQ(x.size()-1, x.at(-1).idx()); 37 | EXPECT_EQ(x.size()-3, x.at(-3).idx()); 38 | } 39 | 40 | TEST(sparse_range_iterator, sub) 41 | { 42 | sparse_range x(0, 20, 2); 43 | EXPECT_EQ(x.at(4).sub(3), sparse_range(8, 14, 2)); 44 | EXPECT_EQ(x.at(7).sub(-3), sparse_range(8, 14, 2)); 45 | EXPECT_EQ(x.at(4).sub(), sparse_range(8, 20, 2)); 46 | EXPECT_EQ(x.at(4).subcpy(3), sparse_range(8, 14, 2)); 47 | EXPECT_EQ(x.at(7).subcpy(-3), sparse_range(8, 14, 2)); 48 | EXPECT_EQ(x.at(4).subcpy(), sparse_range(8, 20, 2)); 49 | } 50 | -------------------------------------------------------------------------------- /test/sparse_range_struct.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace core; 6 | 7 | TEST(sparse_range_struct, base_constructor) 8 | { 9 | sparse_range x(0, 10); 10 | EXPECT_EQ(0, x.start); 11 | EXPECT_EQ(10, x.finish); 12 | EXPECT_EQ(1, x.step); 13 | 14 | sparse_range y(0, 10, 2); 15 | EXPECT_EQ(0, y.start); 16 | EXPECT_EQ(10, y.finish); 17 | EXPECT_EQ(2, y.step); 18 | } 19 | 20 | TEST(sparse_range_struct, copy_constructor) 21 | { 22 | sparse_range y(5, 10); 23 | sparse_range x(y); 24 | EXPECT_EQ(x, y); 25 | } 26 | 27 | TEST(sparse_range_struct, index) 28 | { 29 | sparse_range x(0, 16, 2); 30 | EXPECT_EQ(8, x.size()); 31 | 32 | EXPECT_EQ(0, *x.at(0)); 33 | EXPECT_EQ(4, *x.at(2)); 34 | EXPECT_EQ(14, *x.at(-1)); 35 | EXPECT_EQ(10, *x.at(-3)); 36 | 37 | EXPECT_EQ(0, x.get(0)); 38 | EXPECT_EQ(4, x.get(2)); 39 | EXPECT_EQ(14, x.get(-1)); 40 | EXPECT_EQ(10, x.get(-3)); 41 | 42 | EXPECT_EQ(0, x[0]); 43 | EXPECT_EQ(4, x[2]); 44 | EXPECT_EQ(14, x[-1]); 45 | EXPECT_EQ(10, x[-3]); 46 | 47 | EXPECT_EQ(0, x.front()); 48 | EXPECT_EQ(14, x.back()); 49 | 50 | EXPECT_EQ(0, *x.begin()); 51 | EXPECT_EQ(14, *x.rbegin()); 52 | } 53 | 54 | TEST(sparse_range_struct, sub) 55 | { 56 | sparse_range x(0, 16, 2); 57 | sparse_range y(4, 12, 2); 58 | 59 | // positive start and end 60 | EXPECT_EQ(y, x.sub(2, 6)); 61 | EXPECT_EQ(y, x.subcpy(2, 6)); 62 | 63 | // positive start, negative end 64 | EXPECT_EQ(y, x.sub(2, -2)); 65 | EXPECT_EQ(y, x.subcpy(2, -2)); 66 | 67 | // negative start and end 68 | EXPECT_EQ(y, x.sub(-6, -2)); 69 | EXPECT_EQ(y, x.subcpy(-6, -2)); 70 | 71 | // negative start, positive end 72 | EXPECT_EQ(y, x.sub(-6, 6)); 73 | EXPECT_EQ(y, x.subcpy(-6, 6)); 74 | 75 | y = sparse_range(8, 16, 2); 76 | // single input 77 | EXPECT_EQ(y, x.sub(4)); 78 | EXPECT_EQ(y, x.sub(-4)); 79 | EXPECT_EQ(y, x.subcpy(4)); 80 | EXPECT_EQ(y, x.subcpy(-4)); 81 | 82 | // ref 83 | EXPECT_EQ(x, x.sub()); 84 | EXPECT_EQ(y, y.sub()); 85 | } 86 | 87 | TEST(sparse_range_struct, swap) 88 | { 89 | sparse_range x(0, 10); 90 | sparse_range y(10, 15); 91 | EXPECT_EQ(sparse_range(0, 10), x); 92 | EXPECT_EQ(sparse_range(10, 15), y); 93 | x.swap(y); 94 | EXPECT_EQ(sparse_range(0, 10), y); 95 | EXPECT_EQ(sparse_range(10, 15), x); 96 | } 97 | 98 | TEST(sparse_range_struct, compare) 99 | { 100 | sparse_range x(0, 10); 101 | sparse_range y(10, 0); 102 | 103 | EXPECT_TRUE(x < y); 104 | EXPECT_FALSE(x > y); 105 | EXPECT_TRUE(x <= y); 106 | EXPECT_FALSE(x >= y); 107 | EXPECT_FALSE(x == y); 108 | EXPECT_TRUE(x != y); 109 | 110 | x = sparse_range(0, 5); 111 | y = sparse_range(0, 10); 112 | 113 | EXPECT_TRUE(x < y); 114 | EXPECT_FALSE(x > y); 115 | EXPECT_TRUE(x <= y); 116 | EXPECT_FALSE(x >= y); 117 | EXPECT_FALSE(x == y); 118 | EXPECT_TRUE(x != y); 119 | 120 | x = y; 121 | 122 | EXPECT_FALSE(x < y); 123 | EXPECT_FALSE(x > y); 124 | EXPECT_TRUE(x <= y); 125 | EXPECT_TRUE(x >= y); 126 | EXPECT_TRUE(x == y); 127 | EXPECT_FALSE(x != y); 128 | 129 | x = sparse_range(0, 10, 2); 130 | y = sparse_range(10, 0, -2); 131 | 132 | EXPECT_TRUE(x < y); 133 | EXPECT_FALSE(x > y); 134 | EXPECT_TRUE(x <= y); 135 | EXPECT_FALSE(x >= y); 136 | EXPECT_FALSE(x == y); 137 | EXPECT_TRUE(x != y); 138 | 139 | x = sparse_range(0, 5, 2); 140 | y = sparse_range(0, 10, 2); 141 | 142 | EXPECT_TRUE(x < y); 143 | EXPECT_FALSE(x > y); 144 | EXPECT_TRUE(x <= y); 145 | EXPECT_FALSE(x >= y); 146 | EXPECT_FALSE(x == y); 147 | EXPECT_TRUE(x != y); 148 | 149 | x = y; 150 | 151 | EXPECT_FALSE(x < y); 152 | EXPECT_FALSE(x > y); 153 | EXPECT_TRUE(x <= y); 154 | EXPECT_TRUE(x >= y); 155 | EXPECT_TRUE(x == y); 156 | EXPECT_FALSE(x != y); 157 | } 158 | --------------------------------------------------------------------------------