I've ported some standard library facilities like vector, algorithm, etc. to my kernel so I can code in C++ instead of C. This is one of them. I'm looking for concerns regarding:
- Performance
- Safety
- Friendly interface
Perhaps there are more idiomatic ways to accomplish what I'm going for?
#ifndef _LIBCPP_STRING_H_
#define _LIBCPP_STRING_H_
#include <prefix.h>
#include <libc/stddef.h>
#include <libc/string.h>
#include <libc/stdint.h>
#include "algorithm.h"
namespace std
{
template<size_t Size>
class fixed_string
{
public:
static constexpr size_t npos = static_cast<size_t>(UINT32_MAX);
fixed_string() :
_length(0)
{
_buffer[0] = '\0';
}
fixed_string(const char *string)
{
assign(string, strlen(string));
}
fixed_string(const fixed_string &other)
{
assign(other._buffer, other._length);
}
fixed_string &operator =(const fixed_string &other)
{
assign(other._buffer, other._length);
return *this;
}
fixed_string &operator =(const char *string)
{
assign(string, strlen(string));
return *this;
}
bool operator ==(const fixed_string &other) const
{
if(_length != other._length)
return false;
return (strcmp(other._buffer, _buffer) == 0);
}
bool operator ==(const char *string) const
{
return (strcmp(string, _buffer) == 0);
}
bool operator !=(const fixed_string &other) const
{
return !(*this == other);
}
bool operator !=(const char *string) const
{
return !(*this == string);
}
size_t find(const fixed_string &other) const
{
return find(other._buffer, _length);
}
size_t find(const char *other) const
{
return find(other, strlen(other));
}
size_t find(const char *other, size_t length) const
{
size_t found = 0;
char *buffer = _buffer;
while(*buffer)
{
if(found >= length)
{
size_t diff = ((buffer - found) - _buffer);
return diff;
}
found = (*buffer == other[found]) ? found + 1 : 0;
buffer ++;
}
return npos;
}
const char *c_str() const { return _buffer; }
size_t length() const { return _length; }
private:
void assign(const char *string, size_t length)
{
if(!string)
{
_buffer[0] = '\0';
_length = 0;
return;
}
_length = std::min(length, Size);
strlcpy(_buffer, string, _length);
}
char _buffer[Size + 1];
size_t _length;
};
}
#endif /* _LIBCPP_STRING_H_ */