kranewm

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in C++
git clone git://git.deurzen.net/kranewm
Log | Files | Refs | LICENSE

cycle.hh (4445B)


      1 #ifndef __CYCLE_H_GUARD__
      2 #define __CYCLE_H_GUARD__
      3 
      4 #include "../winsys/common.hh"
      5 #include "../winsys/geometry.hh"
      6 
      7 #include <cstdlib>
      8 #include <deque>
      9 #include <vector>
     10 #include <optional>
     11 #include <unordered_map>
     12 #include <variant>
     13 
     14 enum class StackAction
     15 {
     16     Insert,
     17     Remove
     18 };
     19 
     20 template <typename T>
     21 class HistoryStack final
     22 {
     23     static_assert(std::is_pointer<T>::value,
     24         "Only pointer types may be stored in a history stack.");
     25 
     26 public:
     27     HistoryStack();
     28     ~HistoryStack();
     29 
     30     void clear();
     31     void push_back(T);
     32     void replace(T, T);
     33     std::optional<T> peek_back() const;
     34     std::optional<T> pop_back();
     35     void remove(T);
     36 
     37     std::vector<T> const& as_vector() const;
     38 
     39 private:
     40     std::vector<T> m_stack;
     41 
     42 };
     43 
     44 template <typename T>
     45 class Cycle final
     46 {
     47     static_assert(std::is_pointer<T>::value,
     48         "Only pointer types may be stored in a cycle.");
     49 
     50 public:
     51     Cycle(std::vector<T>, bool);
     52     Cycle(std::initializer_list<T>, bool);
     53     ~Cycle();
     54 
     55     bool next_will_wrap(winsys::Direction) const;
     56     bool empty() const;
     57     bool contains(T) const;
     58     bool is_active_element(T) const;
     59     bool is_active_index(Index) const;
     60 
     61     std::size_t size() const;
     62     std::size_t length() const;
     63 
     64     std::optional<Index> index() const;
     65     Index active_index() const;
     66     Index last_index() const;
     67     Index next_index(winsys::Direction) const;
     68     Index next_index_from(Index, winsys::Direction) const;
     69 
     70     std::optional<Index> index_of_element(const T) const;
     71 
     72     std::optional<T> next_element(winsys::Direction) const;
     73     std::optional<T> active_element() const;
     74     std::optional<T> prev_active_element() const;
     75     std::optional<T> element_at_index(Index) const;
     76     std::optional<T> element_at_front(T) const;
     77     std::optional<T> element_at_back(T) const;
     78 
     79     void activate_first();
     80     void activate_last();
     81     void activate_at_index(Index);
     82     void activate_element(T);
     83 
     84     template<typename UnaryPredicate>
     85     void activate_for_condition(UnaryPredicate predicate)
     86     {
     87         auto it = std::find_if(
     88             m_elements.begin(),
     89             m_elements.end(),
     90             predicate
     91         );
     92 
     93         if (it != m_elements.end())
     94             activate_element(*it);
     95     }
     96 
     97     bool remove_first();
     98     bool remove_last();
     99     bool remove_at_index(Index);
    100     bool remove_element(T);
    101 
    102     template<typename UnaryPredicate>
    103     bool remove_for_condition(UnaryPredicate predicate)
    104     {
    105         auto it = std::find_if(
    106             m_elements.begin(),
    107             m_elements.end(),
    108             predicate
    109         );
    110 
    111         if (it != m_elements.end())
    112             return remove_element(*it);
    113 
    114         return false;
    115     }
    116 
    117     std::optional<T> pop_back();
    118 
    119     void replace_element(T, T);
    120     void swap_elements(T, T);
    121     void swap_indices(Index, Index);
    122 
    123     void reverse();
    124     void rotate(winsys::Direction);
    125     void rotate_range(winsys::Direction, Index, Index);
    126     std::optional<T> cycle_active(winsys::Direction);
    127     std::optional<T> drag_active(winsys::Direction);
    128 
    129     void insert_at_front(T);
    130     void insert_at_back(T);
    131     void insert_before_index(Index, T);
    132     void insert_after_index(Index, T);
    133     void insert_before_element(T, T);
    134     void insert_after_element(T, T);
    135 
    136     void clear();
    137 
    138     std::deque<T> const& as_deque() const;
    139     std::vector<T> const& stack() const;
    140 
    141     typename std::deque<T>::iterator
    142     begin()
    143     {
    144         return m_elements.begin();
    145     }
    146 
    147     typename std::deque<T>::const_iterator
    148     begin() const
    149     {
    150         return m_elements.begin();
    151     }
    152 
    153     typename std::deque<T>::const_iterator
    154     cbegin() const
    155     {
    156         return m_elements.cbegin();
    157     }
    158 
    159     typename std::deque<T>::iterator
    160     end()
    161     {
    162         return m_elements.end();
    163     }
    164 
    165     typename std::deque<T>::const_iterator
    166     end() const
    167     {
    168         return m_elements.end();
    169     }
    170 
    171     typename std::deque<T>::const_iterator
    172     cend() const
    173     {
    174         return m_elements.cend();
    175     }
    176 
    177     T operator[](std::size_t index)
    178     {
    179         return m_elements[index];
    180     }
    181 
    182     const T operator[](std::size_t index) const
    183     {
    184         return m_elements[index];
    185     }
    186 
    187 private:
    188     Index m_index;
    189 
    190     std::deque<T> m_elements;
    191 
    192     bool m_unwindable;
    193     HistoryStack<T> m_stack;
    194 
    195     void sync_active();
    196 
    197     void push_index_to_stack(std::optional<Index>);
    198     void push_active_to_stack();
    199     std::optional<T> get_active_from_stack();
    200 
    201 };
    202 
    203 #endif//__CYCLE_H_GUARD__