#include <string>
#include <algorithm>
#include <ostream>
class taille_illegale {};
class indice_invalide {};
class petite_chaine {
enum { MAX = 255 };
char txt_[MAX + 1] {};
template <class T>
static bool est_taille_valide(T val) { // ici: spécialiser pour T unsigned? valider T integral?
return 0 <= val && val <= MAX;
}
void taille(unsigned char val) { // précondition: est_taille_valide(val)
*reinterpret_cast<unsigned char*>(&txt_[0]) = val;
}
public:
using size_type = std::size_t; // suggestion
//
// itérateurs (suggestion; pas demandé)
//
using iterator = char*;
using const_iterator = const char*;
iterator begin() noexcept {
return &txt_[1];
}
iterator end() noexcept {
return begin() + size();
}
const_iterator begin() const noexcept {
return &txt_[1];
}
const_iterator end() const noexcept {
return begin() + size();
}
const_iterator cbegin() const noexcept {
return begin();
}
const_iterator cend() const noexcept {
return end();
}
petite_chaine() = default;
petite_chaine(const std::string &s) {
using namespace std;
if (!est_taille_valide(s.size()))
throw taille_illegale{};
copy(begin(s), end(s), begin());
taille(s.size());
}
// précondition: p == nullptr || p est valide
petite_chaine(const char *p) {
if (!p)
taille(0);
else {
size_type n = 0;
for (; *p && n <= MAX; ++n, ++p)
txt_[n + 1] = *p;
if (*p)
throw taille_illegale{};
taille(n);
}
}
size_type size() const {
return *reinterpret_cast<const unsigned char*>(&txt_[0]);
}
bool empty() const {
return size() == 0;
}
bool operator==(const petite_chaine &autre) const {
return size() == autre.size() && std::equal(begin(), end(), autre.begin());
}
bool operator!=(const petite_chaine &autre) const {
return !(*this == autre);
}
bool operator < (const petite_chaine &autre) const {
return std::lexicographical_compare(begin(), end(), autre.begin(), autre.end());
}
bool operator <= (const petite_chaine &autre) const {
return !(autre < *this);
}
bool operator > (const petite_chaine &autre) const {
return autre < *this;
}
bool operator >= (const petite_chaine &autre) const {
return !(*this < autre);
}
friend std::ostream& operator<<(std::ostream &os, const petite_chaine &s) {
for(auto c : s) // Ok si on a défini begin() et end() correctement
os << c;
return os;
}
char& operator[](size_type n) {
// if (n >= size()) throw indice_invalide{};
return txt_[n + 1];
}
char operator[](size_type n) const {
// if (n >= size()) throw indice_invalide{};
return txt_[n + 1];
}
};