gigaTerminal text editor | 
          
| git clone git://git.dimitrijedobrota.com/giga.git | 
| Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | 775a7a593487d6aa4ecc25975feaec4069b5c02a | 
| parent | 6d35b46728c76b2e9ca7d1ee62ba214d3f35a903 | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Sat, 8 Mar 2025 19:27:12 +0100 | 
Ensure enum safety with concepts
| M | source/layout_dynamic.cpp | | | +++++++++++++++++ -------------- | 
| M | source/layout_dynamic.hpp | | | ++++++++++++++++++++++ ------ | 
2 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/ source/layout_dynamic.cpp b/ source/layout_dynamic.cpp
          @@ -112,24 +112,21 @@ 
          Panel* Panel::close()
        
        
            return std::visit(visit_parent, m_parent->m_payload);
          }
          Panel* Panel::select(Panel* sel, Direction dir)
          template<Panel::Direction D>
            requires is_enum_valid_v<Panel::Direction, D>
          Panel* Panel::select(Panel* sel)
          {
            const auto& sele = sel->get_elem();
            pos_t tpos = {0, 0};
            switch (dir) {
              case Direction::Up:
                tpos = sele.apos() + pos_t(0, -1);
                break;
              case Direction::Left:
                tpos = sele.apos() + pos_t(-1, 0);
                break;
              case Direction::Down:
                tpos = sele.apos() + pos_t(0UL, sele.ahgt().value());
                break;
              case Direction::Right:
                tpos = sele.apos() + pos_t(sele.awth().value(), 0UL);
                break;
            if constexpr (D == Direction::Up) {
              tpos = sele.apos() + pos_t(0, -1);
            } else if (D == Direction::Left) {
              tpos = sele.apos() + pos_t(-1, 0);
            } else if (D == Direction::Down) {
              tpos = sele.apos() + pos_t(0UL, sele.ahgt().value());
            } else if (D == Direction::Right) {
              tpos = sele.apos() + pos_t(sele.awth().value(), 0UL);
            }
            const auto& roote = get_elem();
        
        
          @@ -174,6 +171,7 @@ 
          Panel* Panel::select(pos_t tpos)
        
        
          }
          template<Panel::Split T>
            requires is_enum_valid_v<Panel::Split, T>
          Panel* Panel::split()
          {
            const auto visit_parent = [&]<typename M>(M& pcont) -> Panel*
        
        
          @@ -224,4 +222,9 @@ 
          Panel* Panel::split()
        
        
          template Panel* Panel::split<Panel::Split::Horizontal>();
          template Panel* Panel::split<Panel::Split::Vertical>();
          template Panel* Panel::select<Panel::Direction::Up>(Panel*);
          template Panel* Panel::select<Panel::Direction::Left>(Panel*);
          template Panel* Panel::select<Panel::Direction::Right>(Panel*);
          template Panel* Panel::select<Panel::Direction::Down>(Panel*);
          }  // namespace display
        
        diff --git a/ source/layout_dynamic.hpp b/ source/layout_dynamic.hpp
@@ -10,6 +10,16 @@
namespace display
          {
          template<typename T>
          concept is_enum_type_v = std::is_enum_v<T>;
          template<typename T>
          concept is_enum_count_v = requires { T::_count; };
          template<typename T, T Val>
          concept is_enum_valid_v = is_enum_type_v<T> && is_enum_count_v<T>
              && requires { requires(Val >= T {} && Val < T::_count); };
          class Panel
          {
          public:
        
        
          @@ -19,6 +29,7 @@ 
          public:
        
        
            {
              Horizontal,
              Vertical,
              _count,  // NOLINT
            };
            enum class Direction : std::uint8_t
        
        
          @@ -26,7 +37,8 @@ 
          public:
        
        
              Up,
              Left,
              Down,
              Right
              Right,
              _count,  // NOLINT
            };
            Panel(Panel* parent, plc_t aplc, layout_t::ptr_t&& child)
        
        
          @@ -47,10 +59,14 @@ 
          public:
        
        
            void render() const;
            template<Split T>
              requires is_enum_valid_v<Split, T>
            Panel* split();
            template<Direction D>
              requires is_enum_valid_v<Direction, D>
            Panel* select(Panel* sel);
            Panel* close();
            Panel* select(Panel* sel, Direction dir);
          private:
            const Element& get_elem() const
        
        
          @@ -177,13 +193,13 @@ 
          void LayoutDynamic<T>::input(event& evnt)
        
        
              } else if (evnt.key() == 'x') {
                m_sel = m_sel->close();
              } else if (evnt.key() == 'w') {
                m_sel = m_container.select(m_sel, Panel::Direction::Up);
                m_sel = m_container.select<Panel::Direction::Up>(m_sel);
              } else if (evnt.key() == 'a') {
                m_sel = m_container.select(m_sel, Panel::Direction::Left);
                m_sel = m_container.select<Panel::Direction::Left>(m_sel);
              } else if (evnt.key() == 's') {
                m_sel = m_container.select(m_sel, Panel::Direction::Down);
                m_sel = m_container.select<Panel::Direction::Down>(m_sel);
              } else if (evnt.key() == 'd') {
                m_sel = m_container.select(m_sel, Panel::Direction::Right);
                m_sel = m_container.select<Panel::Direction::Right>(m_sel);
              } else {
                m_sel->layout().input(evnt);
              }