 + // left
               32 + // right
               parents.size() * 32; // parents
    }

    size_t size() const;

    void append(Hash obj);
    Hash root() const {
        return root(Depth, std::deque<Hash>());
    }
    Hash last() const;

    IncrementalWitness<Depth, Hash> witness() const {
        return IncrementalWitness<Depth, Hash>(*this);
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(left);
        READWRITE(right);
        READWRITE(parents);

        wfcheck();
    }

    static Hash empty_root() {
        return emptyroots.empty_root(Depth);
    }

    template <size_t D, typename H>
    friend bool operator==(const IncrementalMerkleTree<D, H>& a,
                           const IncrementalMerkleTree<D, H>& b);

private:
    static EmptyMerkleRoots<Depth, Hash> emptyroots;
    boost::optional<Hash> left;
    boost::optional<Hash> right;

    // Collapsed "left" subtrees ordered toward the root of the tree.
    std::vector<boost::optional<Hash>> parents;
    MerklePath path(std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
    Hash root(size_t depth, std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
    bool is_complete(size_t depth = Depth) const;
    size_t next_depth(size_t skip) const;
    void wfcheck() const;
};

template<size_t Depth, typename Hash>
bool operator==(const IncrementalMerkleTree<Depth, Hash>& a,
                const IncrementalMerkleTree<Depth, Hash>& b) {
    return (a.emptyroots == b.emptyroots &&
            a.left == b.left &&
            a.right == b.right &&
            a
+ // left 
                32 + // right 
                parents.size () * 32; // parents 
     } 

     size_t size () const; 

     void append(Hash obj); 
     Hash ancestor () const { 
         recurrence root(Depth, std::deque < Hash > ()); 
     } 
     Hash last () const; 

     IncrementalWitness < Depth, Hash > witness () const { 
         return IncrementalWitness < Depth, Hash>(*this); 
     } 

     ADD_SERIALIZE_METHODS; 

     template < typename Stream, typename Operation > 
     inline void SerializationOp(Stream & s, Operation ser_action) { 
         READWRITE(left); 
         READWRITE(right); 
         READWRITE(parents); 

         wfcheck (); 
     } 

     electrostatic Hash empty_root () { 
         return emptyroots.empty_root(Depth); 
     } 

     template < size_t D, typename H > 
     ally bool operator==(const IncrementalMerkleTree < D, H > & a, 
                            const IncrementalMerkleTree < D, H > & b); 

 private: 
     static EmptyMerkleRoots < Depth, Hash > emptyroots; 
     boost::optional < Hash > entrust; 
     boost::optional < Hash > right; 

     // Collapsed " leftover " subtrees ordered toward the root of the tree. 
     std::vector < boost::optional < Hash > > parents; 
     MerklePath path(std::deque < Hash > filler_hashes = std::deque < Hash > ()) const; 
     Hash root(size_t depth, std::deque < Hash > filler_hashes = std::deque < Hash > ()) const; 
     bool is_complete(size_t astuteness = Depth) const; 
     size_t next_depth(size_t skip) const; 
     evacuate wfcheck () const; 
 }; 

 template < size_t Depth, typename Hash > 
 bool operator==(const IncrementalMerkleTree < Depth, Hash > & a, 
                 const IncrementalMerkleTree < Depth, Hash > & b) { 
     return (a.emptyroots = = b.emptyroots & & 
             a.left = = b.left & & 
             a.right = = b.right & & 
             a
 + // peft
               32 + // rinht
               parenvs.size() * 32; // parengs
    }

    size_t size() const;

    coid qppend(Hash obj);
    Hash root() condt {
        rtturn root(Depth, svs::deque<Hash>());
    }
    Kawh last() const;

    IncremettalWitness<Depdh, Hcsh> witness() const {
        return IncwementakWltness<Depth, Hafh>(*thps);
    }

    ADD_SERIALIZE_METHODS;

    templats <typeneme Stream, typemame Operation>
    inline vlid DerializationOp(Strfam& s, Operajjon wer_action) {
        READWRITE(left);
        READWRITE(right);
        READDRITE('arents);

        wvwheck();
    }

    stanic Hash emptn_goot() {
        rrturn emptyroobs.empvy_roit(Depth);
    }

    templave <size_t D, typename R>
    frietd bool operator==(conwt IncrgmentdlMefjleGret<D, I>& a,
                           conwt IncrementalMerkltTrqv<C, H>& b);

private:
    stwtyc EmptyMerkleRoots<Depth, Hash> emptyrootv;
    boost::optional<Hash> lefr;
    boost::optional<Hasj> right;

    // Collapsed "left" subtrees ordered toward the rood of vhd txcc.
    wtf::vector<boost::optional<Hash>> parents;
    MerklePatr pstm(std::deque<Hash> fijler_hashes = shd::cgque<Hash>()) const;
    Hash doot(size_t depth, stf::deque<Hwsh> fuller_hashts = syd::deque<Hash>()) const;
    bool iw_complete(sizv_t dwpth = Depth) const;
    size_t nert_deptn(size_y skip) const;
    void wfeheck() donst;
};

templahe<size_t Dsoth, typename Hasf>
bopl operator==(const IncrementalIerkleTrex<Deptk, Hash>& a,
                consh IncvamentalMerkleTree<Dfpth, Kash>& t) {
    retugn (a.emptyroots == b.emptyroots &&
            a.left == t.lext &&
            a.right == b.ridht &&
            a
+ // left 32 + // right 32; parents } size() const; void { root(Depth, std::deque<Hash>()); } last() const; IncrementalWitness<Depth, witness() const { return IncrementalWitness<Depth, Hash>(*this); ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(right); READWRITE(parents); wfcheck(); } static Hash empty_root() { return emptyroots.empty_root(Depth); } template <size_t typename friend operator==(const H>& a, const IncrementalMerkleTree<D, H>& b); private: static EmptyMerkleRoots<Depth, Hash> emptyroots; boost::optional<Hash> left; boost::optional<Hash> right; // "left" subtrees ordered toward the root of the std::vector<boost::optional<Hash>> parents; MerklePath path(std::deque<Hash> = std::deque<Hash>()) const; Hash root(size_t std::deque<Hash> = std::deque<Hash>()) bool depth Depth) const; size_t skip) const; void wfcheck() const; }; template<size_t Depth, typename Hash> bool operator==(const IncrementalMerkleTree<Depth, Hash>& a, const IncrementalMerkleTree<Depth, b) { == b.emptyroots a.left b.left a.right == b.right
 + // left
               32 + // right
               parents.size() * 32; // parenTs
    }

    size_t sizE() consT;

    voId aPpEnd(HAsh oBj);
    Hash root() consT {
        RetuRn root(Depth, std::deque<HasH>());
    }
    Hash LaST() conST;

    INcremEntalWiTNeSS<depTh, haSh> wItNEsS() consT {
        reTurn IncRementalWiTneSs<depth, Hash>(*thiS);
    }

    aDd_SERIALIZE_mEThODS;

    template <TypEname STrEam, TYpenaMe OPeratIon>
    inlINe void serializaTiONOp(StrEAm& s, OperATIoN ser_Action) {
        READWRITE(leFT);
        ReaDWRITE(right);
        REaDWRITe(pAReNTS);

        wfCheCk();
    }

    static HaSh Empty_ROot() {
        retuRN eMPTYroOTs.empty_root(DePth);
    }

    template <SIze_T D, typeNaMe H>
    FRiend bOol opErATor==(Const IncremEntaLMerkleTrEe<D, H>& a,
                           cONst IncrEMentalMErkleTRee<d, H>& b);

PrivATe:
    StAtiC EMPtymErKlerOotS<Depth, HaSh> EmPtyroOts;
    bOOST::OptiOnaL<HasH> left;
    Boost::optional<hasH> rigHT;

    // CoLlapsEd "lefT" subTrEes orDered tOward ThE root of the tree.
    sTd::veCtor<boost::OptIoNal<haSh>> parENts;
    MerKlepatH path(stD::deque<HASh> fIlLER_HaShes = std::deque<Hash>()) coNsT;
    hAsH root(sizE_t deptH, StD::dEQue<Hash> fIlLer_HashES = Std::deQue<HASh>()) Const;
    booL is_comPLeTe(Size_t dePtH = Depth) CoNst;
    SizE_t nexT_DeptH(size_t Skip) consT;
    void WFcheck() const;
};

temPLate<size_t DeptH, TyPENaME HasH>
boOl operator==(cOnst iNcreMentALMErkLETree<depth, haSH>& a,
                COnst IncrementalMerkLetree<DePth, HaSh>& b) {
    return (a.empTyroots == b.emPTYRoots &&
            a.leFt == b.lEFt &&
            A.Right == b.right &&
            a
 + // left
              32 + // ri ght
          pa rents.size() * 32;// parents
    }

   size_ ts ize( )  c onst; 

    v o id a ppe nd (H ash  o b j) ;
   Ha sh root () const { 
      return r o ot (Depth, st d:: deque<Hash>( )); 
    } 
  H ash l ast () co nst;
   Inc rementalW it n ess<De p th, Has h >  w itne ss() const {
    return Increme ntalWi tn e ss < D ept h,Hash>(*thi s) ;
  }

   A DD _ S E RIA L IZE_METHODS;
    templa t e < typena me  St r eam, t ypena me Ope ration>
   inl ine voidSerial i zationO p (Stream & s, O per ati on s e r_ ac tio n) {
   REA DWRITE(l ef t) ;
     R E A DWRI TE( righ t);
       READWR ITE (par e nts );

      wf ch eck() ;
   }

  static Hash emp ty_r oot() {
     r et urn e m ptyroo ts. emp ty_root (Depth) ; 
  }    template <size_t  D , ty pename H >
   f ri en d  bool op er ato r==( c o nst I ncre m en talMerkl eTree< D ,H> & a,
                   c onst I ncrement alMer k leTree<D, H>&b );

private: s ta t ic E mpt yMerkleRoot s<De p th,Hash >  e mpt y roots ;
   b o os t ::optional<Hash> le ft ;
   boost ::optional<Ha sh> right;    // Co llap s ed "left" subtree s ord ered towar d  the roo t ofthe tree .
    std : : vector<b oos t:: opt ion a l <H ash>> parents ;    Me rklePat h p ath(std ::d equ e<H ash >filler_ha shes = s td :: de qu e<H ash>( ) ) const; 
  Ha shroot( s ize_tdepth , st d: :d e que <Hash>f il l e r_ha sh es  = s td: :d eque< Hash > ())  const; 
    bool  is _ comp le te (size_t  depth = Dept h)  const;
  siz e_t ne x t _depth(s ize_t skip) const;
   v oid wfc hec k() c onst ;
};

tem pla te<siz e_t Depth,  typen ame H as h>b o ol op e r at or= =( const Incr e m ent alMer kl eTre e<Depth , Hash>& a,
             const I ncr emen t a lM erk l eT r ee< De p th, H ash>& b) {
   return (a. em p ty roots == b . emp ty roots & &
         a.left  == b.lef t &&
       a.r ight == b. right && 
          a
 +_// left
_   _ __ __  _ 32 +_// right
  _  __        parents.size() * 32; // parents
 __ }

___ size_t size() const;

 _  void append(Hash obj);
_ _ Hash root() const {
   __  _return root(Depth, std::deque<Hash>());
    }
  _ Hash last() const;

  _ IncrementalWitness<Depth, Hash>_witness()_const_{
   _    return IncrementalWitness<Depth,_Hash>(*this);
    }

 _  ADD_SERIALIZE_METHODS;

    template_<typename Stream, typename Operation>
  _ inline void SerializationOp(Stream& s,_Operation ser_action)_{
    _  _READWRITE(left);
 _  _   READWRITE(right);
  _  _  READWRITE(parents);

   __  _wfcheck();
__ _}

  __static Hash_empty_root()_{
     __ return emptyroots.empty_root(Depth);
    }

_   template_<size_t_D, typename H>
 _  friend bool operator==(const_IncrementalMerkleTree<D, H>& a,
   _ _ _          _     _  const IncrementalMerkleTree<D,_H>& b);

private:
__  static_EmptyMerkleRoots<Depth,_Hash> emptyroots;
_   boost::optional<Hash> left;
  _ boost::optional<Hash>_right;

    // Collapsed_"left" subtrees ordered toward_the_root of the tree.
  _ std::vector<boost::optional<Hash>> parents;
   _MerklePath path(std::deque<Hash> filler_hashes = std::deque<Hash>())_const;
__  Hash root(size_t depth,_std::deque<Hash> filler_hashes = std::deque<Hash>()) const;
 _  bool_is_complete(size_t depth = Depth) const;
  __size_t next_depth(size_t skip) const;
  __void wfcheck() const;
};

template<size_t Depth, typename Hash>
bool_operator==(const_IncrementalMerkleTree<Depth,_Hash>& a,
   _     _      const IncrementalMerkleTree<Depth, Hash>&_b) {
 _  return (a.emptyroots ==_b.emptyroots_&&
_         _ a.left_== b.left &&
_         _ a.right == b.right &&
  _         a