I am looking for people's opinions on my use of a set of non standard "standard classes". Basically I am working on a 'modern' C++ Lexical Analyser and Parser Generator duo to replace flex and GNU Bison which will work as a library and tool combination.
I have a number of non standard extensions of std
library classes. The reason I am needing these nonstandard classes is to be able to express algorithms more succinctly and nearer the mathematical equivalents.
Here's a vector class that allows extension via operator[]
, which also has a generic Base
parameter, allowing the vector to be based at 1 rather than zero, for example. And I return indices as size_t
's rather than iterators as indexes are more useful in a traditional mathematical sense.
//
// vector.h - auto sizing 'vector' class
//
// Copyright (c) 2015-2016 Aaron Nathaniel Gray under the MIT License
//
#include <vector>
#include <iostream>
template<typename T, size_t Base = 0>
class vector : public std::vector<T> {
public:
vector() : std::vector<T>() {}
vector(const std::initializer_list<T> il) : std::vector<T>(il) {}
~vector() {}
iterator last() { return end() - 1; }
const_iterator clast() const { return end - 1; }
size_t size() const { return std::vector<T>::size(); }
void resize(size_t _size) { std::vector<T>::resize(_size); }
T& operator [] (size_t index) {
if (index + 1 - Base > size())
resize(index + 1 - Base);
return std::vector<T>::operator[](index - Base);
}
const T operator [] (size_t index) const {
if (index + 1 - Base <= size())
return std::vector<T>::operator[](index - Base);
else
return T();
}
signed find(const T& value) {
auto i = std::find(cbegin(), cend(), value);
if (i != cend())
return i - cbegin() + Base;
else
return -1;
}
size_t add(const T value = T()) {
push_back(value);
return size() - 1 + Base;
}
std::string toString() const;
};
template<typename T, size_t Base = 0>
std::string vector<T, Base>::toString() const {
std::stringstream ss;
for (size_t element = Base; element < size() + Base; ++element) {
ss << (*this)[element];
if (element < size() + Base)
ss << ",";
ss << std::endl;
}
return ss.str();
}
I am wondering whether to use the namespace nonstd::vector
.
I also have non-standard set, deque
, and a very extensive bitset
class.
Example:
nonstd::vector<size_t> accept;
for(auto state : states) {
.... accept = ....
this->accept[state->index] = accept;
}
Here, state->index
may not be sequential or contiguous and maximum value not known, so push_back
will not work.
And a find example:
nonstd::vector<Production*> productions;
...
size_t productionIndex = production.find(aProduction);
std::vector
would not work. \$\endgroup\$Vector
with the capitalV
to further differentiate fromstd::vector
. \$\endgroup\$