Skip to main content
Became Hot Network Question
Remove concerns and tags from title; minor formatting fixes
Source Link
Toby Speight
  • 88.7k
  • 14
  • 104
  • 327

C++20 MinMaxStack : Should I use std::totally_ordered<T> or a C++20 custom concept for a template constraint?- tracks minimum and maximum values

I'm implementing a MinMaxStack<T> in C++20C++20 that tracks minimum and maximum values. The class needs T to support <<, >>, and ==== operators. Could you please do a code review for this? and 

I have two questionquestions regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better/simpler ideas please let me know.

2)Is requires std::constructible_from<T, U> accurate for the method push?

  1. I'm unsure whether to use a standard concept or to define a custom concept with minimal requirements. If you have better/simpler ideas please let me know.

  2. Is requires std::constructible_from<T, U> accurate for the method push()?

https://godbolt.org/z/T1b9TTMYaLive demo

C++20 MinMaxStack : Should I use std::totally_ordered<T> or a C++20 custom concept for a template constraint?

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? and I have two question regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better/simpler ideas please let me know.

2)Is requires std::constructible_from<T, U> accurate for the method push?

https://godbolt.org/z/T1b9TTMYa

MinMaxStack - tracks minimum and maximum values

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? 

I have two questions regarding requires in the code:

  1. I'm unsure whether to use a standard concept or to define a custom concept with minimal requirements. If you have better/simpler ideas please let me know.

  2. Is requires std::constructible_from<T, U> accurate for the method push()?

Live demo

added 10 characters in body
Source Link
sam
  • 503
  • 2
  • 9

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? adand I have two question regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better/simpler ideas please let me know. 3

2)Is requires std::constructible_from<T, U> accurate for the method push?

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? ad I have two question regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better ideas please let me know. 3)Is requires std::constructible_from<T, U> accurate for the method push?

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? and I have two question regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better/simpler ideas please let me know.

2)Is requires std::constructible_from<T, U> accurate for the method push?

Source Link
sam
  • 503
  • 2
  • 9

C++20 MinMaxStack : Should I use std::totally_ordered<T> or a C++20 custom concept for a template constraint?

I'm implementing a MinMaxStack<T> in C++20 that tracks minimum and maximum values. The class needs T to support <, >, and == operators. Could you please do a code review for this? ad I have two question regarding requires in the code:

1)I'm unsure whether to use a standard concept or define a custom concept with minimal requirements. If you have better ideas please let me know. 3)Is requires std::constructible_from<T, U> accurate for the method push?

https://godbolt.org/z/T1b9TTMYa

Option 1: Standard concept on class

#include <concepts>
#include <stack>

template <typename T>
    requires std::totally_ordered<T>
class MinMaxStack {
public:
    using Stack = std::stack<T>;
    using size_type = typename Stack::size_type;
    using value_type = T;

    template <typename U>
        requires std::constructible_from<T, U>
    void push(U&& value) {
        T v{std::forward<U>(value)};
        
        const bool isNewMin = m_mins.empty() || v <= m_mins.top();
        const bool isNewMax = m_maxs.empty() || v >= m_maxs.top();
        
        m_data.push(std::move(v));
        
        if (isNewMin) m_mins.push(m_data.top());
        if (isNewMax) m_maxs.push(m_data.top());
    }

    void pop() {
        if (empty()) {
            return;
        }
        
        const auto& top = m_data.top();
        const bool isMin = (top == m_mins.top());
        const bool isMax = (top == m_maxs.top());
        
        m_data.pop();
        
        if (isMin) m_mins.pop();
        if (isMax) m_maxs.pop();
    }

    [[nodiscard]] const T* top() const noexcept {
        if (empty()) {
            return nullptr;
        }
        return &m_data.top();
    }

    [[nodiscard]] const T* getMin() const noexcept {
        if (empty()) {
            return nullptr;
        }
        return &m_mins.top();
    }

    [[nodiscard]] const T* getMax() const noexcept {
        if (empty()) {
            return nullptr;
        }
        return &m_maxs.top();
    }

    [[nodiscard]] size_type size() const noexcept {
        return m_data.size();
    }

    [[nodiscard]] bool empty() const noexcept {
        return m_data.empty();
    }

private:
    Stack m_data;
    Stack m_mins;
    Stack m_maxs;
};
  

Option 2: Custom minimal concept

#include <concepts>
#include <stack>

template <typename T>
concept MinMaxComparable = requires(const T& a, const T& b) {
    { a < b }  -> std::convertible_to<bool>;
    { a > b }  -> std::convertible_to<bool>;
    { a == b } -> std::convertible_to<bool>;
};

template <typename T>
    requires MinMaxComparable<T>
class MinMaxStack {
public:
    template <typename U>
        requires std::constructible_from<T, U>
    void push(U&& value);
    
    // ... same implementation
};