duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

checks.hpp (5501B)


      1 #ifndef C4_YML_DETAIL_CHECKS_HPP_
      2 #define C4_YML_DETAIL_CHECKS_HPP_
      3 
      4 #include "c4/yml/tree.hpp"
      5 
      6 #ifdef __clang__
      7 #   pragma clang diagnostic push
      8 #elif defined(__GNUC__)
      9 #   pragma GCC diagnostic push
     10 #   pragma GCC diagnostic ignored "-Wtype-limits" // error: comparison of unsigned expression >= 0 is always true
     11 #elif defined(_MSC_VER)
     12 #   pragma warning(push)
     13 #   pragma warning(disable: 4296/*expression is always 'boolean_value'*/)
     14 #endif
     15 
     16 namespace c4 {
     17 namespace yml {
     18 
     19 
     20 void check_invariants(Tree const& t, size_t node=NONE);
     21 void check_free_list(Tree const& t);
     22 void check_arena(Tree const& t);
     23 
     24 
     25 //-----------------------------------------------------------------------------
     26 //-----------------------------------------------------------------------------
     27 //-----------------------------------------------------------------------------
     28 
     29 inline void check_invariants(Tree const& t, size_t node)
     30 {
     31     if(node == NONE)
     32     {
     33         if(t.size() == 0) return;
     34         node = t.root_id();
     35     }
     36 
     37     auto const& n = *t._p(node);
     38 #ifdef RYML_DBG
     39     if(n.m_first_child != NONE || n.m_last_child != NONE)
     40     {
     41         printf("check(%zu): fc=%zu lc=%zu\n", node, n.m_first_child, n.m_last_child);
     42     }
     43     else
     44     {
     45         printf("check(%zu)\n", node);
     46     }
     47 #endif
     48 
     49     C4_CHECK(n.m_parent != node);
     50     if(n.m_parent == NONE)
     51     {
     52         C4_CHECK(t.is_root(node));
     53     }
     54     else //if(n.m_parent != NONE)
     55     {
     56         C4_CHECK(t.has_child(n.m_parent, node));
     57 
     58         auto const& p = *t._p(n.m_parent);
     59         if(n.m_prev_sibling == NONE)
     60         {
     61             C4_CHECK(p.m_first_child == node);
     62             C4_CHECK(t.first_sibling(node) == node);
     63         }
     64         else
     65         {
     66             C4_CHECK(p.m_first_child != node);
     67             C4_CHECK(t.first_sibling(node) != node);
     68         }
     69 
     70         if(n.m_next_sibling == NONE)
     71         {
     72             C4_CHECK(p.m_last_child == node);
     73             C4_CHECK(t.last_sibling(node) == node);
     74         }
     75         else
     76         {
     77             C4_CHECK(p.m_last_child != node);
     78             C4_CHECK(t.last_sibling(node) != node);
     79         }
     80     }
     81 
     82     C4_CHECK(n.m_first_child != node);
     83     C4_CHECK(n.m_last_child != node);
     84     if(n.m_first_child != NONE || n.m_last_child != NONE)
     85     {
     86         C4_CHECK(n.m_first_child != NONE);
     87         C4_CHECK(n.m_last_child != NONE);
     88     }
     89 
     90     C4_CHECK(n.m_prev_sibling != node);
     91     C4_CHECK(n.m_next_sibling != node);
     92     if(n.m_prev_sibling != NONE)
     93     {
     94         C4_CHECK(t._p(n.m_prev_sibling)->m_next_sibling == node);
     95         C4_CHECK(t._p(n.m_prev_sibling)->m_prev_sibling != node);
     96     }
     97     if(n.m_next_sibling != NONE)
     98     {
     99         C4_CHECK(t._p(n.m_next_sibling)->m_prev_sibling == node);
    100         C4_CHECK(t._p(n.m_next_sibling)->m_next_sibling != node);
    101     }
    102 
    103     size_t count = 0;
    104     for(size_t i = n.m_first_child; i != NONE; i = t.next_sibling(i))
    105     {
    106 #ifdef RYML_DBG
    107         printf("check(%zu):               descend to child[%zu]=%zu\n", node, count, i);
    108 #endif
    109         auto const& ch = *t._p(i);
    110         C4_CHECK(ch.m_parent == node);
    111         C4_CHECK(ch.m_next_sibling != i);
    112         ++count;
    113     }
    114     C4_CHECK(count == t.num_children(node));
    115 
    116     if(n.m_prev_sibling == NONE && n.m_next_sibling == NONE)
    117     {
    118         if(n.m_parent != NONE)
    119         {
    120             C4_CHECK(t.num_children(n.m_parent) == 1);
    121             C4_CHECK(t.num_siblings(node) == 1);
    122         }
    123     }
    124 
    125     if(node == t.root_id())
    126     {
    127         C4_CHECK(t.size() == t.m_size);
    128         C4_CHECK(t.capacity() == t.m_cap);
    129         C4_CHECK(t.m_cap == t.m_size + t.slack());
    130         check_free_list(t);
    131         check_arena(t);
    132     }
    133 
    134     for(size_t i = t.first_child(node); i != NONE; i = t.next_sibling(i))
    135     {
    136         check_invariants(t, i);
    137     }
    138 }
    139 
    140 
    141 //-----------------------------------------------------------------------------
    142 //-----------------------------------------------------------------------------
    143 //-----------------------------------------------------------------------------
    144 
    145 inline void check_free_list(Tree const& t)
    146 {
    147     if(t.m_free_head == NONE)
    148     {
    149         C4_CHECK(t.m_free_tail == t.m_free_head);
    150         return;
    151     }
    152 
    153     C4_CHECK(t.m_free_head >= 0 && t.m_free_head < t.m_cap);
    154     C4_CHECK(t.m_free_tail >= 0 && t.m_free_tail < t.m_cap);
    155 
    156     auto const& head = *t._p(t.m_free_head);
    157     //auto const& tail = *t._p(t.m_free_tail);
    158 
    159     //C4_CHECK(head.m_prev_sibling == NONE);
    160     //C4_CHECK(tail.m_next_sibling == NONE);
    161 
    162     size_t count = 0;
    163     for(size_t i = t.m_free_head, prev = NONE; i != NONE; i = t._p(i)->m_next_sibling)
    164     {
    165         auto const& elm = *t._p(i);
    166         if(&elm != &head)
    167         {
    168             C4_CHECK(elm.m_prev_sibling == prev);
    169         }
    170         prev = i;
    171         ++count;
    172     }
    173     C4_CHECK(count == t.slack());
    174 }
    175 
    176 
    177 //-----------------------------------------------------------------------------
    178 //-----------------------------------------------------------------------------
    179 //-----------------------------------------------------------------------------
    180 
    181 inline void check_arena(Tree const& t)
    182 {
    183     C4_CHECK(t.m_arena.len == 0 || (t.m_arena_pos >= 0 && t.m_arena_pos <= t.m_arena.len));
    184     C4_CHECK(t.arena_size() == t.m_arena_pos);
    185     C4_CHECK(t.arena_slack() + t.m_arena_pos == t.m_arena.len);
    186 }
    187 
    188 
    189 } /* namespace yml */
    190 } /* namespace c4 */
    191 
    192 #ifdef __clang__
    193 #   pragma clang diagnostic pop
    194 #elif defined(__GNUC__)
    195 #   pragma GCC diagnostic pop
    196 #elif defined(_MSC_VER)
    197 #   pragma warning(pop)
    198 #endif
    199 
    200 #endif /* C4_YML_DETAIL_CHECKS_HPP_ */