# as a non-submodule
git clone --recursive https://github.com/mgood7123/StringAdapter
## as a submodule
git submodule add https://github.com/mgood7123/StringAdapter path/to/StringAdapter
git submodule update --init --recursive
# building and testing
make test_debugStringAdapter is a C++11 compatible library, exposing string manipulation capabilities for any given type
ALL PROVIDED DATA STRUCTURES ARE HASHABLE AND COMPARABLE
we provide 4 types of adapters: ListAdapter, ForwardListAdapter, VectorAdapter, and ResizingListAdapter
for demonstration we provide a char implementation of each adapter
CharVectorAdapter using VectorAdapter
CharResizingVectorAdapter using ResizingVectorAdapter
CharListAdapter using ListAdapter
CharForwardListAdapter using ForwardListAdapter
the most basic and common adapter, utilises std::vector to hold its data
equivilant to a PointerAdapter
PointerAdapter was going to be included however pointer arithmatic proved to be too difficult and std::vector implements most of what we needed
a less common adapter, utilises std::vector to hold its data, automatically grows and shrinks to fit its data, useful for very large data
equivilant to a PointerAdapter
PointerAdapter was going to be included however pointer arithmatic proved to be too difficult and std::vector implements most of what we needed
a common adapter, utilises std::list to hold its data, this is equivilant to a linked list
a common adapter, utilises std::forward_list to hold its data, this is equivilant to a reversed linked list
all data entered is reversed, 123\0 -> \0321
index 0 is the item after the \0
the base adapter BasicStringAdapter<T> provide the following functions
Slice* slice(std::size_t start, std::size_t end)
const CSlice* cslice(std::size_t start, std::size_t end)
const CSlice* slice(std::size_t start, std::size_t end) constprovides a Slice of an adapter
for reasons of virtual functions, slice and cslice return an allocated Slice and allocated CSlice object, which must be deleted via the delete operator
a Slice represents a region of an adapter
Slice provides
iterator begin()
iterator end()
reverse_iterator rbegin()
reverse_iterator rend()
T & operator[] (const std::size_t index)
const std::size_t get_start()
const std::size_t get_end()
virtual BasicStringAdapter<T> * get_origin()CSlice is the const version of Slice
CSlice provides
const const_iterator begin()
const const_iterator end()
const const_iterator cbegin()
const const_iterator cend()
const const_reverse_iterator rbegin()
const const_reverse_iterator rend()
const const_reverse_iterator crbegin()
const const_reverse_iterator crend()
const T & operator[] (const std::size_t index)
const std::size_t get_start()
const std::size_t get_end()
virtual const BasicStringAdapter<T> * get_origin()a subslice can be created by using auto subslice = slice->get_origin()->slice(slice->get_start(), slice->get_end());
iterator begin()
const const_iterator begin() const
const const_iterator cbegin() const
iterator end()
const const_iterator end() const
const const_iterator cend() const
reverse_iterator rbegin()
const const_reverse_iterator rbegin() const
const const_reverse_iterator crbegin() const
reverse_iterator rend()
const const_reverse_iterator rend() const
const const_reverse_iterator crend() constadapter specific indexed-iterators for begin, end and their reverse counterparts rbegin and rend
required for for loop (specifically for( VALUE_HERE : ADAPTER_HERE )) capabilities
virtual T & get_item_at_index(const std::size_t index)
virtual const T & get_item_at_index(const std::size_t index) constcalled by operator[] (const std::size_t index)
T & operator[] (const std::size_t index)
const T & operator[] (const std::size_t index) constyour basic array index operator, arr[5] = value
virtual Shared<T> data()
virtual const CShared<T> data() constreturns a contigous array of data
this must never return nullptr, NULL, an address of 0x0, or an integer zero ( return 0; )
this returns a managed Shared object, functions include T * ptr() const, const std::size_t length() const, and const std::size_t lengthInBytes() const
Shared is a wrapper for std::shared_ptr and contains additional information such as the length of the pointer array
CShared is a const version of Shared
this returns a managed CShared object, functions include const T * ptr() const, const std::size_t length() const, and const std::size_t lengthInBytes() const
virtual std::vector<T>* data_as_vector()
virtual const std::vector<T>* data_as_vector() constreturns the data as a std::vector
virtual const std::size_t length() constreturns the length of the data, excluding the EOF marker (the get_end_of_file() function)
virtual const std::size_t line_count() constreturns the number of lines contained in the data, using the get_new_line() function
virtual void resize(const std::size_t capacity)resizes the adapter to the specified capacity
const std::size_t size() constreturns length()
const bool operator == (const BasicStringAdapter<T> & other) const
const bool operator != (const BasicStringAdapter<T> & other) constcompares the contents of one adapter with the contents of another adapter
virtual Shared<T> c_str_()
virtual const CShared<T> c_str_() const
virtual Shared<char> c_str()
virtual const CShared<char> c_str() constsame usage as data() and data_is_allocated()
c_str() is expected to return data that outlives its owner:
CharVectorAdapter a = "hi";
// a holds a ref to shared_ptr<vector<char>>
auto a_data = a.data();
// a_data holds no ref to shared_ptr<vector<char>> since vec->data() already returns char* thus we can directly reference it, avoiding a useless copy
auto a_c_str = a.c_str();
// a_c_str same as a_data but we hold a ref to shared_ptr<vector<char>> to uphold expectations of b_c_str and a_c_str can both be used out of scope
CharListAdapter b = "hi";
// b holds no ref to list<char>
auto b_data = b.data();
// b_data holds no ref to list<char>
auto b_c_str = b.c_str();
// b_c_str holds no ref to list<char> since we must convert from list<char> to char*returns the contents as a Shared<char> which can be accessed as a char * string via ptr()
this should be a one way T -> char* conversion for each element T
thus should be a one way Shared<T> -> Shared<char> conversion for each element Shared<T>
IMPORTANT: there is no char* -> T conversion as std::string requires since reversing a conversion may be impossible
IMPLEMENTATION: it is recommended to implement c_str_() and friends, and return a suitible Shared<T>, subclasses should implement c_str() calling c_str_() and if needed, converting the result to Shared<char>
this allows intermediate conversion of the returned Shared<T> required for a string which data() might not consider, in the case of ForwardListAdapter it flips the string so the EOF is at the end instead of the start, \0ih -> hi\0
void to_string() constprints this object to std::cout, intended for << base << derived << more_derived and so on
const int strcmp(const BasicStringAdapter<T> & other) const
const int strcmp(const char * other) const
const int strcmp(const T * other, const std::size_t len) constcompares content
for a ranged for loop is used for direct comparison of elements
strcmp(const char * other) should be reserved for when T is char
virtual void append_(const BasicStringAdapter<T> & what)appends the contents of the specified adapter what to the end of this adapter
this calls insert_ with a pos of -1
virtual void insert_(const BasicStringAdapter<T> & what, const std::size_t pos)inserts the contents of the specified adapter what to the specified pos of this adapter
pos is bound to the start and end of the adapter
virtual void replace_(const BasicStringAdapter<T> & what, const std::size_t pos, const std::size_t length)replaces the contents of this adapter, at the specified position pos, with the specified length length, with the contents of the specified adapter what
pos is bound to the start and end of the adapter
length is bound to the end of the adapter in accordance to the pos
virtual void erase_(const std::size_t pos, const std::size_t length)erases the contents of this adapter, at the specified position pos, with the specified length length
pos is bound to the start and end of the adapter
length is bound to the end of the adapter in accordance to the pos
const std::size_t clamp_pos(const std::size_t pos) const
const std::size_t clamp_pos(const std::size_t length, const std::size_t pos) const
const std::size_t clamp_length(const std::size_t clamped_pos, const std::size_t len) const
const std::size_t clamp_length(const std::size_t length, const std::size_t clamped_pos, const std::size_t len) constclamps the pos and len based on the specified length
length is typically the result of size() or length()
virtual const T get_new_line() constobtains the new line element, for char this is typically \n
the 4 adapters provide everything that BasicStringAdapter<T> provides above (basic functions)
with the following additional functions
NAME(const T & new_line, const T & eof)
NAME(const T* ptr, const T & new_line, const T & eof)
NAME(const CShared<T> & ptr, const T & new_line, const T & eof)
NAME(const T* ptr, const std::size_t length, const T & new_line, const T & eof)
NAME(const CShared<T> & ptr, const std::size_t length, const T & new_line, const T & eof)
NAME(const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
NAME(const T* ptr, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
NAME(const CShared<T> & ptr, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
NAME(const T* ptr, const std::size_t length, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
NAME(const CShared<T> & ptr, const std::size_t length, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
void init(const T* ptr, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof)
void init(const T* ptr, const std::size_t length, const std::shared_ptr<const T> & new_line, const std::shared_ptr<const T> & eof) template <typename T>
struct ListAdapter : public BasicStringAdapter<T> {
mutable std::list<T> list;
mutable std::size_t len;
using BASE = BasicStringAdapter<T>;
BASIC_STRING_ADAPTER_USING_BASE(BASE);
// this uses `init` in constructors
BASIC_STRING_ADAPTER_USING_BASE_CONSTRUCTORS(ListAdapter, T)
// ...
};std::vector<DERIVED> split(const T & splitter) constsplits an adapter into the same adapter delimited by the specified splitter
abcd<SPLITTER>efg -> [ "abcd", "efg" ]
std::vector<DERIVED> lines() constsplits an adapter into the same adapter delimited by the new line item, returned by get_new_line()
abcd\nefg -> [ "abcd", "efg" ]
std::vector<DERIVED> lines() constsplits an adapter into the same adapter delimited by the new line item, returned by get_new_line()
abcd\nefg -> [ "abcd", "efg" ]
all Char Adapters provide everything the 4 adapters provides above (basic functions + additional functions)
with the following additional functions
const char_t get_end_of_file() constreturns the EOF marker, for char this is the null terminator which is \0
void append(const std::string & s)
void append(const char_t * s)
void append(const char_t * s, std::size_t len)
void append(const char_t & c)calls append_
void insert(const std::size_t pos, const std::string & s)
void insert(const std::size_t pos, const char * s)
void insert(const std::size_t pos, const char * s, const std::size_t len2)
void insert(const std::size_t pos, const char & s)calls insert_
void replace(const std::size_t pos, const std::size_t len, const std::string & s)
void replace(const std::size_t pos, const std::size_t len, const char * s)
void replace(const std::size_t pos, const std::size_t len, const char * s, const std::size_t len2)
void replace(const std::size_t pos, const std::size_t len, const char & s)calls replace_
void erase(const std::size_t pos, const std::size_t len)calls erase_