Chaîne pascal avec itérateurs

#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];
   }
};

Valid XHTML 1.0 Transitional

CSS Valide !