1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#pragma once


#include <concepts><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <utility>


#include "internal/dev_env.hpp"


namespace uni {


template<class In, class Out = In>
struct queue_by_stack {
    static_assert(std::same_as<typename In::value_type, typename Out::value_type>);
    static_assert(std::common_reference_with<typename In::size_type, typename Out::size_type>);

    using value_type = In::value_type;
    using size_type = std::common_type_t<typename In::size_type, typename Out::size_type>;

  protected:
    In _in;
    Out _out;

  private:
    inline void _shift() noexcept(NO_EXCEPT) {
        if(!this->_out.empty()) return;

        while(!this->_in.empty()) {
            this->_out.push(this->_in.top());
            this->_in.pop();
        }
    }

  public:
    queue_by_stack() noexcept = default;

    inline bool empty() const noexcept(NO_EXCEPT) {
        return this->_in.empty() && this->_out.empty();
    }

    inline auto size() const noexcept(NO_EXCEPT) {
        return this->_in.size() + this->_out.size();
    }


    inline decltype(auto) front() noexcept(NO_EXCEPT) {
        this->_shift();
        assert(!this->_out.empty());
        return this->_out.top();
    }

    template<std::convertible_to<value_type> T = value_type>
        requires std::is_move_constructible_v<T>
    inline decltype(auto) front_or(T&& val) const noexcept(NO_EXCEPT) {
        if(this->empty()) return static_cast<value_type>(std::forward<T>(val));
        else return this->front();
    }


    inline auto& clear() noexcept(NO_EXCEPT) {
        this->_in.clear(), this->_out.clear();
        return *this;
    }


    template<std::convertible_to<value_type> T = value_type>
    inline auto& push(T&& val) noexcept(NO_EXCEPT) {
        this->_in.push(std::forward<T>(val));
        return *this;
    }

    template<class... Args>
    inline decltype(auto) emplace(Args&&... args) noexcept(NO_EXCEPT) {
        return this->_in.emplace(std::forward<Args>(args)...);
    }


    auto& pop() noexcept(NO_EXCEPT) {
        this->_shift();
        assert(!this->_out.empty());

        this->_out.pop();
        return *this;
    }
};



} // namespace uni