refactor(bar): prefer standard unique_ptr
parent
8d5b61a9fd
commit
6ff296a4b0
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
#include "util/ptr_vec.hpp"
|
|
||||||
|
|
||||||
#include <gdk/gdkwayland.h>
|
#include <gdk/gdkwayland.h>
|
||||||
|
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
@ -33,7 +31,7 @@ namespace waybar {
|
||||||
struct zwlr_layer_shell_v1 *layer_shell;
|
struct zwlr_layer_shell_v1 *layer_shell;
|
||||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||||
struct wl_seat *seat;
|
struct wl_seat *seat;
|
||||||
util::ptr_vec<Bar> bars;
|
std::vector<std::unique_ptr<Bar>> bars;
|
||||||
|
|
||||||
Client(int argc, char* argv[]);
|
Client(int argc, char* argv[]);
|
||||||
void bind_interfaces();
|
void bind_interfaces();
|
||||||
|
|
|
@ -1,823 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <initializer_list>
|
|
||||||
#include <numeric>
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
namespace waybar::util {
|
|
||||||
|
|
||||||
/// Joins a sequence of strings, separating them using `js`
|
|
||||||
template<class StrIterator> // Models InputIterator<std::string>
|
|
||||||
std::string join_strings(StrIterator b, StrIterator e, std::string_view js = ", ")
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
std::for_each(b, e, [&](auto&& s) {
|
|
||||||
if (!result.empty()) {
|
|
||||||
result.append(js);
|
|
||||||
}
|
|
||||||
result.append(s);
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* nonull(const char* str) {
|
|
||||||
if (str == nullptr) return "";
|
|
||||||
return str;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool iequals(std::string_view a, std::string_view b)
|
|
||||||
{
|
|
||||||
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
|
|
||||||
[](char a, char b) { return tolower(a) == tolower(b); });
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool starts_with(std::string_view prefix, std::string_view a)
|
|
||||||
{
|
|
||||||
return a.compare(0, prefix.size(), prefix) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool ends_with(std::string_view prefix, std::string_view a)
|
|
||||||
{
|
|
||||||
return a.compare(a.size() - prefix.size(), prefix.size(), prefix) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a closure which compares the adress any reference to T to the address of t
|
|
||||||
template<typename T>
|
|
||||||
constexpr auto addr_eq(T&& t) {
|
|
||||||
return [&t] (auto&& t2) {
|
|
||||||
return &t == &t2;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool erase_this(std::vector<T>& cont, T* el)
|
|
||||||
{
|
|
||||||
if (el < cont.data() && el >= cont.data() + cont.size()) return false;
|
|
||||||
cont.erase(cont.begin() + (el - cont.data()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool erase_this(std::vector<T>& cont, T& el)
|
|
||||||
{
|
|
||||||
return erase_this(cont, &el);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<class Func, int... ns>
|
|
||||||
constexpr auto generate_array_impl(std::integer_sequence<int, ns...>&&, Func&& gen)
|
|
||||||
{
|
|
||||||
return std::array<std::decay_t<decltype(std::invoke(gen, std::declval<int>()))>,
|
|
||||||
sizeof...(ns)>{{std::invoke(gen, ns)...}};
|
|
||||||
}
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<int n, class Func>
|
|
||||||
constexpr auto generate_array(Func&& gen)
|
|
||||||
{
|
|
||||||
auto intseq = std::make_integer_sequence<int, n>();
|
|
||||||
return detail::generate_array_impl(std::move(intseq), std::forward<Func>(gen));
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace view {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<typename T>
|
|
||||||
using store_or_ref_t = std::conditional_t<std::is_rvalue_reference_v<T>, std::decay_t<T>, T&>;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
struct reverse {
|
|
||||||
|
|
||||||
reverse(Cont&& cont) noexcept : _container(std::forward<Cont>(cont)) {}
|
|
||||||
|
|
||||||
auto begin()
|
|
||||||
{
|
|
||||||
return std::rbegin(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end()
|
|
||||||
{
|
|
||||||
return std::rend(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto begin() const
|
|
||||||
{
|
|
||||||
return std::rbegin(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end() const
|
|
||||||
{
|
|
||||||
return std::rend(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cbegin() const
|
|
||||||
{
|
|
||||||
return std::crbegin(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cend() const
|
|
||||||
{
|
|
||||||
return std::crend(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::store_or_ref_t<Cont&&> _container;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ContRef>
|
|
||||||
reverse(ContRef&& cont) -> reverse<ContRef&&>;
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
struct constant {
|
|
||||||
constant(Cont&& cont) noexcept : _container(std::forward<Cont>(cont)){};
|
|
||||||
|
|
||||||
auto begin() const
|
|
||||||
{
|
|
||||||
return std::cbegin(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto end() const
|
|
||||||
{
|
|
||||||
return std::cend(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cbegin() const
|
|
||||||
{
|
|
||||||
return std::cbegin(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cend() const
|
|
||||||
{
|
|
||||||
return std::cend(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
detail::store_or_ref_t<Cont&&> _container;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ContRef>
|
|
||||||
constant(ContRef&& cont) -> constant<ContRef&&>;
|
|
||||||
|
|
||||||
} // namespace view
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Range algorithms
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename InputIt, typename Size, typename F>
|
|
||||||
constexpr InputIt for_each_n(InputIt&& first, Size n, F&& f)
|
|
||||||
{
|
|
||||||
for (Size i = 0; i < n; ++first, ++i) {
|
|
||||||
std::invoke(f, *first);
|
|
||||||
}
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `for_each` with access to an index value. Function called as `f(*it, i)`
|
|
||||||
///
|
|
||||||
/// For each item in range `[first, last)`, invoke `f` with args
|
|
||||||
/// `*iter, i` where `iter` is the current iterator, and `i` is
|
|
||||||
/// an incrementing value, starting at zero. Use this instead of
|
|
||||||
/// raw indexed loops wherever possible.
|
|
||||||
///
|
|
||||||
/// \param first Input iterator to the begining of the range
|
|
||||||
/// \param last Input iterator to the end of the range
|
|
||||||
/// \param f Must be invocable with arguments `value_type`, `std::size_t`
|
|
||||||
/// \returns The number of iterations performed
|
|
||||||
template<typename InputIt, typename F>
|
|
||||||
constexpr std::size_t indexed_for(InputIt&& first, InputIt&& last, F&& f)
|
|
||||||
{
|
|
||||||
std::size_t i = 0;
|
|
||||||
std::for_each(std::forward<InputIt>(first), std::forward<InputIt>(last), [&](auto&& a) {
|
|
||||||
std::invoke(f, a, i);
|
|
||||||
i++;
|
|
||||||
});
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Rng, typename F>
|
|
||||||
constexpr std::size_t indexed_for(Rng&& rng, F&& f)
|
|
||||||
{
|
|
||||||
return indexed_for(std::begin(rng), std::end(rng), std::forward<F>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// `for_each_n` with access to an index value. Function called as `f(*it, i)`
|
|
||||||
///
|
|
||||||
/// for `n` iterations, invoke `f` with args `*iter, i`
|
|
||||||
/// where `iter` is the current iterator starting with `first`,
|
|
||||||
/// and `i` is an incrementing value, starting at zero.
|
|
||||||
/// Use this instead of raw indexed loops wherever possible.
|
|
||||||
///
|
|
||||||
/// \param first Input iterator to the begining of the range
|
|
||||||
/// \param n Number of iterations to go through
|
|
||||||
/// \param f Must be invocable with arguments `value_type`, `std::size_t`
|
|
||||||
/// \returns An iterator one past the last one visited
|
|
||||||
template<class InputIt, class Size, class F>
|
|
||||||
constexpr InputIt indexed_for_n(InputIt first, Size n, F&& f)
|
|
||||||
{
|
|
||||||
for (Size i = 0; i < n; ++first, ++i) {
|
|
||||||
std::invoke(f, *first, i);
|
|
||||||
}
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Rng, class Size, class F>
|
|
||||||
constexpr std::size_t indexed_for_n(Rng&& rng, Size n, F&& f)
|
|
||||||
{
|
|
||||||
return indexed_for_n(std::begin(rng), std::end(rng), n, std::forward<F>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Iter1, typename Iter2, typename F>
|
|
||||||
constexpr void for_both(Iter1&& f1, Iter1&& l1, Iter2&& f2, Iter2&& l2, F&& f)
|
|
||||||
{
|
|
||||||
Iter1 i1 = std::forward<Iter1>(f1);
|
|
||||||
Iter2 i2 = std::forward<Iter2>(f2);
|
|
||||||
for (; i1 != l1 && i2 != l2; i1++, i2++) {
|
|
||||||
std::invoke(f, *i1, *i2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Rng1, typename Rng2, typename F>
|
|
||||||
constexpr void for_both(Rng1&& r1, Rng2&& r2, F&& f)
|
|
||||||
{
|
|
||||||
for_both(std::begin(r1), std::end(r1), std::begin(r2), std::end(r2), std::forward<F>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Range based standard algorithms
|
|
||||||
*
|
|
||||||
* Thanks, chris from SO!
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
constexpr auto accumulate(Cont&& cont, T&& init)
|
|
||||||
{
|
|
||||||
// TODO C++20: std::accumulate is constexpr
|
|
||||||
using std::begin, std::end;
|
|
||||||
auto first = begin(cont);
|
|
||||||
auto last = end(cont);
|
|
||||||
for (; first != last; ++first) init = init + *first;
|
|
||||||
return init;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T, typename BinaryOperation>
|
|
||||||
constexpr auto accumulate(Cont&& cont, T&& init, BinaryOperation&& op)
|
|
||||||
{
|
|
||||||
// TODO C++20: std::accumulate is constexpr
|
|
||||||
using std::begin, std::end;
|
|
||||||
auto first = begin(cont);
|
|
||||||
auto last = end(cont);
|
|
||||||
for (; first != last; ++first) init = op(init, *first);
|
|
||||||
return init;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator>
|
|
||||||
decltype(auto) adjacent_difference(Cont&& cont, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::adjacent_difference(begin(cont), end(cont), std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) prev_permutation(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::prev_permutation(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) prev_permutation(Cont&& cont, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::prev_permutation(begin(cont), end(cont), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) push_heap(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::push_heap(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) push_heap(Cont&& cont, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::push_heap(begin(cont), end(cont), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
decltype(auto) remove(Cont&& cont, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::remove(begin(cont), end(cont), std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename T>
|
|
||||||
decltype(auto) remove_copy(Cont&& cont, OutputIterator&& first, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::remove_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename UnaryPredicate>
|
|
||||||
decltype(auto) remove_copy_if(Cont&& cont, OutputIterator&& first, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::remove_copy_if(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) remove_if(Cont&& cont, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::remove_if(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T, typename T2>
|
|
||||||
decltype(auto) replace(Cont&& cont, T&& old_value, T2&& new_value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::replace(begin(cont), end(cont), std::forward<T>(old_value),
|
|
||||||
std::forward<T2>(new_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename T, typename T2>
|
|
||||||
decltype(auto) replace_copy(Cont&& cont, OutputIterator&& first, T&& old_value, T2&& new_value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::replace_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<T>(old_value), std::forward<T2>(old_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename UnaryPredicate, typename T>
|
|
||||||
decltype(auto) replace_copy_if(Cont&& cont,
|
|
||||||
OutputIterator&& first,
|
|
||||||
UnaryPredicate&& p,
|
|
||||||
T&& new_value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::replace_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<UnaryPredicate>(p), std::forward<T>(new_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate, typename T>
|
|
||||||
decltype(auto) replace_if(Cont&& cont, UnaryPredicate&& p, T&& new_value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::replace_if(begin(cont), end(cont), std::forward<UnaryPredicate>(p),
|
|
||||||
std::forward<T>(new_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) reverse(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::reverse(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator>
|
|
||||||
decltype(auto) reverse_copy(Cont&& cont, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::reverse_copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename ForwardIterator>
|
|
||||||
decltype(auto) rotate(Cont&& cont, ForwardIterator&& new_first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::rotate(begin(cont), std::forward<ForwardIterator>(new_first), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename ForwardIterator, typename OutputIterator>
|
|
||||||
decltype(auto) rotate_copy(Cont&& cont, ForwardIterator&& new_first, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::rotate_copy(begin(cont), std::forward<ForwardIterator>(new_first), end(cont),
|
|
||||||
std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2>
|
|
||||||
decltype(auto) search(Cont&& cont, Cont2&& cont2)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::search(begin(cont), end(cont), begin(cont2), end(cont2));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename BinaryPredicate>
|
|
||||||
decltype(auto) search(Cont&& cont, Cont2&& cont2, BinaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::search(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<BinaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Size, typename T>
|
|
||||||
decltype(auto) search_n(Cont&& cont, Size count, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::search_n(begin(cont), end(cont), count, std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Size, typename T, typename BinaryPredicate>
|
|
||||||
decltype(auto) search_n(Cont&& cont, Size count, T&& value, BinaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::search_n(begin(cont), end(cont), count, std::forward<T>(value),
|
|
||||||
std::forward<BinaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator>
|
|
||||||
decltype(auto) set_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_difference(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
|
|
||||||
decltype(auto) set_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_difference(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator>
|
|
||||||
decltype(auto) set_intersection(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_intersection(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
|
|
||||||
decltype(auto) set_intersection(Cont&& cont,
|
|
||||||
Cont2&& cont2,
|
|
||||||
OutputIterator&& first,
|
|
||||||
Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_intersection(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator>
|
|
||||||
decltype(auto) set_symmetric_difference(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_symmetric_difference(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
|
|
||||||
decltype(auto) set_symmetric_difference(Cont&& cont,
|
|
||||||
Cont2&& cont2,
|
|
||||||
OutputIterator&& first,
|
|
||||||
Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_symmetric_difference(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first),
|
|
||||||
std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator>
|
|
||||||
decltype(auto) set_union(Cont&& cont, Cont2&& cont2, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_union(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename OutputIterator, typename Compare>
|
|
||||||
decltype(auto) set_union(Cont&& cont, Cont2&& cont2, OutputIterator&& first, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::set_union(begin(cont), end(cont), begin(cont2), end(cont2),
|
|
||||||
std::forward<OutputIterator>(first), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UniformRandomNumberGenerator>
|
|
||||||
decltype(auto) shuffle(Cont&& cont, UniformRandomNumberGenerator&& g)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::shuffle(begin(cont), end(cont), std::forward<UniformRandomNumberGenerator>(g));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) sort(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::sort(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) sort(Cont&& cont, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::sort(begin(cont), end(cont), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) sort_heap(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::sort_heap(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) sort_heap(Cont&& cont, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::sort_heap(begin(cont), end(cont), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) stable_partition(Cont&& cont, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::stable_partition(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) stable_sort(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::stable_sort(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) stable_sort(Cont&& cont, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::stable_sort(begin(cont), end(cont), std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename ForwardIterator>
|
|
||||||
decltype(auto) swap_ranges(Cont&& cont, ForwardIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::swap_ranges(begin(cont), end(cont), std::forward<ForwardIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename F>
|
|
||||||
auto transform(Cont&& cont, Cont2&& cont2, F&& f) -> decltype(begin(cont2))
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), begin(cont2), std::forward<F>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Iter, typename F>
|
|
||||||
decltype(auto) transform(Cont&& cont, Iter&& iter, F&& f)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), std::forward<Iter>(iter), std::forward<F>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename Cont3, typename BinaryPredicate>
|
|
||||||
auto transform(Cont&& cont, Cont2&& cont2, Cont3&& cont3, BinaryPredicate&& f)
|
|
||||||
-> decltype(begin(cont2), begin(cont3))
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), begin(cont2), begin(cont3),
|
|
||||||
std::forward<BinaryPredicate>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename InputIterator, typename Cont3, typename BinaryPredicate>
|
|
||||||
auto transform(Cont&& cont, InputIterator&& iter, Cont3&& cont3, BinaryPredicate&& f)
|
|
||||||
-> decltype(begin(cont), begin(cont3))
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), std::forward<InputIterator>(iter), begin(cont3),
|
|
||||||
std::forward<BinaryPredicate>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Cont2, typename InputIterator, typename BinaryPredicate>
|
|
||||||
auto transform(Cont&& cont, Cont2&& cont2, InputIterator&& iter, BinaryPredicate&& f)
|
|
||||||
-> decltype(begin(cont), begin(cont2), iter)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), begin(cont2), std::forward<InputIterator>(iter),
|
|
||||||
std::forward<BinaryPredicate>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename InputIterator, typename OutputIterator, typename BinaryOperation>
|
|
||||||
decltype(auto) transform(Cont&& cont,
|
|
||||||
InputIterator&& firstIn,
|
|
||||||
OutputIterator&& firstOut,
|
|
||||||
BinaryOperation&& op)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::transform(begin(cont), end(cont), std::forward<InputIterator>(firstIn),
|
|
||||||
std::forward<OutputIterator>(firstOut),
|
|
||||||
std::forward<BinaryOperation>(op));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) unique(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::unique(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename BinaryPredicate>
|
|
||||||
decltype(auto) unique(Cont&& cont, BinaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::unique(begin(cont), end(cont), std::forward<BinaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator>
|
|
||||||
decltype(auto) unique_copy(Cont&& cont, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::unique_copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename BinaryPredicate>
|
|
||||||
decltype(auto) unique_copy(Cont&& cont, OutputIterator&& first, BinaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::unique_copy(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<BinaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
decltype(auto) upper_bound(Cont&& cont, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::upper_bound(begin(cont), end(cont), std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T, typename Compare>
|
|
||||||
decltype(auto) upper_bound(Cont&& cont, T&& value, Compare&& comp)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::upper_bound(begin(cont), end(cont), std::forward<T>(value),
|
|
||||||
std::forward<Compare>(comp));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator>
|
|
||||||
decltype(auto) copy(Cont&& cont, OutputIterator&& first)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::copy(begin(cont), end(cont), std::forward<OutputIterator>(first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename OutputIterator, typename UnaryPredicate>
|
|
||||||
decltype(auto) copy_if(Cont&& cont, OutputIterator&& first, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::copy_if(begin(cont), end(cont), std::forward<OutputIterator>(first),
|
|
||||||
std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
decltype(auto) fill(Cont&& cont, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::fill(begin(cont), end(cont), std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
decltype(auto) fill_n(Cont&& cont, std::size_t n, T&& value)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::fill_n(begin(cont), n, std::forward<T>(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) any_of(Cont&& cont, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::any_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) all_of(Cont&& cont, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::all_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) none_of(Cont&& cont, UnaryPredicate&& p)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::none_of(begin(cont), end(cont), std::forward<UnaryPredicate>(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) max_element(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::max_element(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont>
|
|
||||||
decltype(auto) min_element(Cont&& cont)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::min_element(begin(cont), end(cont));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) min_element(Cont&& cont, Compare&& f)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::min_element(begin(cont), end(cont), std::forward<Compare>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename Compare>
|
|
||||||
decltype(auto) max_element(Cont&& cont, Compare&& f)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::max_element(begin(cont), end(cont), std::forward<Compare>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename T>
|
|
||||||
decltype(auto) find(Cont&& cont, T&& t)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::find(begin(cont), end(cont), std::forward<T>(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cont, typename UnaryPredicate>
|
|
||||||
decltype(auto) find_if(Cont&& cont, UnaryPredicate&& f)
|
|
||||||
{
|
|
||||||
using std::begin;
|
|
||||||
using std::end;
|
|
||||||
return std::find_if(begin(cont), end(cont), std::forward<UnaryPredicate>(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace waybar::util
|
|
|
@ -1,581 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <memory>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
|
||||||
#include "algorithm.hpp"
|
|
||||||
|
|
||||||
namespace waybar::util {
|
|
||||||
|
|
||||||
/// An iterator wrapper that dereferences twice.
|
|
||||||
template<typename Iter>
|
|
||||||
struct double_iterator {
|
|
||||||
using wrapped = Iter;
|
|
||||||
|
|
||||||
using value_type = std::decay_t<decltype(*std::declval<typename wrapped::value_type>())>;
|
|
||||||
using difference_type = typename wrapped::difference_type;
|
|
||||||
using reference = value_type&;
|
|
||||||
using pointer = value_type*;
|
|
||||||
using iterator_category = std::random_access_iterator_tag;
|
|
||||||
|
|
||||||
using self_t = double_iterator<Iter>;
|
|
||||||
|
|
||||||
double_iterator(wrapped w) : _iter(std::move(w)) {}
|
|
||||||
double_iterator() : _iter() {}
|
|
||||||
|
|
||||||
reference operator*() const
|
|
||||||
{
|
|
||||||
return (**_iter);
|
|
||||||
}
|
|
||||||
pointer operator->() const
|
|
||||||
{
|
|
||||||
return &(**_iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
self_t& operator++()
|
|
||||||
{
|
|
||||||
_iter.operator++();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
self_t operator++(int i)
|
|
||||||
{
|
|
||||||
return _iter.operator++(i);
|
|
||||||
}
|
|
||||||
self_t& operator--()
|
|
||||||
{
|
|
||||||
_iter.operator--();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
self_t operator--(int i)
|
|
||||||
{
|
|
||||||
return _iter.operator--(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto operator==(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter == rhs._iter;
|
|
||||||
}
|
|
||||||
auto operator!=(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter != rhs._iter;
|
|
||||||
}
|
|
||||||
auto operator<(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter < rhs._iter;
|
|
||||||
}
|
|
||||||
auto operator>(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter > rhs._iter;
|
|
||||||
}
|
|
||||||
auto operator<=(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter <= rhs._iter;
|
|
||||||
}
|
|
||||||
auto operator>=(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter >= rhs._iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
self_t operator+(difference_type d) const noexcept
|
|
||||||
{
|
|
||||||
return _iter + d;
|
|
||||||
}
|
|
||||||
self_t operator-(difference_type d) const noexcept
|
|
||||||
{
|
|
||||||
return _iter - d;
|
|
||||||
}
|
|
||||||
auto operator-(const self_t& rhs) const noexcept
|
|
||||||
{
|
|
||||||
return _iter - rhs._iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
self_t& operator+=(difference_type d)
|
|
||||||
{
|
|
||||||
_iter += d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
self_t& operator-=(difference_type d)
|
|
||||||
{
|
|
||||||
_iter -= d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator wrapped&()
|
|
||||||
{
|
|
||||||
return _iter;
|
|
||||||
}
|
|
||||||
operator const wrapped&() const
|
|
||||||
{
|
|
||||||
return _iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapped& data()
|
|
||||||
{
|
|
||||||
return _iter;
|
|
||||||
}
|
|
||||||
const wrapped& data() const
|
|
||||||
{
|
|
||||||
return _iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
wrapped _iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Iter>
|
|
||||||
auto operator+(typename double_iterator<Iter>::difference_type diff, double_iterator<Iter> iter)
|
|
||||||
{
|
|
||||||
return iter + diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// To avoid clients being moved, they are stored in unique_ptrs, which are
|
|
||||||
/// moved around in a vector. This class is purely for convenience, to still
|
|
||||||
/// have iterator semantics, and a few other utility functions
|
|
||||||
template<typename T>
|
|
||||||
struct ptr_vec {
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<value_type>> _order;
|
|
||||||
|
|
||||||
using iterator = double_iterator<typename decltype(_order)::iterator>;
|
|
||||||
using const_iterator = double_iterator<typename decltype(_order)::const_iterator>;
|
|
||||||
|
|
||||||
using reverse_iterator = double_iterator<typename decltype(_order)::reverse_iterator>;
|
|
||||||
using const_reverse_iterator =
|
|
||||||
double_iterator<typename decltype(_order)::const_reverse_iterator>;
|
|
||||||
|
|
||||||
value_type& push_back(const value_type& v)
|
|
||||||
{
|
|
||||||
auto ptr = std::make_unique<value_type>(v);
|
|
||||||
auto res = ptr.get();
|
|
||||||
_order.push_back(std::move(ptr));
|
|
||||||
return *res;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& push_back(value_type&& v)
|
|
||||||
{
|
|
||||||
auto ptr = std::make_unique<value_type>(std::move(v));
|
|
||||||
auto res = ptr.get();
|
|
||||||
_order.push_back(std::move(ptr));
|
|
||||||
return *res;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& push_back(std::unique_ptr<value_type> ptr)
|
|
||||||
{
|
|
||||||
auto res = ptr.get();
|
|
||||||
_order.push_back(std::move(ptr));
|
|
||||||
return *res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Args>
|
|
||||||
value_type& emplace_back(Args&&... args)
|
|
||||||
{
|
|
||||||
return push_back(std::make_unique<value_type>(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<value_type> erase(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
auto uptr = std::move(*iter);
|
|
||||||
_order.erase(iter);
|
|
||||||
return uptr;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_back(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
|
|
||||||
return rotate_to_back(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_back(iterator iter)
|
|
||||||
{
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
{
|
|
||||||
return std::rotate(iter.data(), iter.data() + 1, _order.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_front(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& uptr) { return uptr.get() == &v; });
|
|
||||||
return rotate_to_front(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_front(iterator iter)
|
|
||||||
{
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
{
|
|
||||||
return std::rotate(_order.begin(), iter.data(), iter.data() + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const noexcept
|
|
||||||
{
|
|
||||||
return _order.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const noexcept
|
|
||||||
{
|
|
||||||
return _order.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t capacity() const noexcept
|
|
||||||
{
|
|
||||||
return _order.capacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t max_size() const noexcept
|
|
||||||
{
|
|
||||||
return _order.max_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(std::size_t new_cap)
|
|
||||||
{
|
|
||||||
_order.reserve(new_cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink_to_fit()
|
|
||||||
{
|
|
||||||
_order.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& operator[](std::size_t n)
|
|
||||||
{
|
|
||||||
return *_order[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& operator[](std::size_t n) const
|
|
||||||
{
|
|
||||||
return *_order[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& at(std::size_t n)
|
|
||||||
{
|
|
||||||
return *_order.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& at(std::size_t n) const
|
|
||||||
{
|
|
||||||
return *_order.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return _order.begin();
|
|
||||||
}
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
return _order.end();
|
|
||||||
}
|
|
||||||
const_iterator begin() const
|
|
||||||
{
|
|
||||||
return _order.begin();
|
|
||||||
}
|
|
||||||
const_iterator end() const
|
|
||||||
{
|
|
||||||
return _order.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rbegin()
|
|
||||||
{
|
|
||||||
return _order.rbegin();
|
|
||||||
}
|
|
||||||
reverse_iterator rend()
|
|
||||||
{
|
|
||||||
return _order.rend();
|
|
||||||
}
|
|
||||||
const_reverse_iterator rbegin() const
|
|
||||||
{
|
|
||||||
return _order.rbegin();
|
|
||||||
}
|
|
||||||
const_reverse_iterator rend() const
|
|
||||||
{
|
|
||||||
return _order.rend();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& front()
|
|
||||||
{
|
|
||||||
return *_order.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& back()
|
|
||||||
{
|
|
||||||
return *_order.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& front() const
|
|
||||||
{
|
|
||||||
return *_order.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& back() const
|
|
||||||
{
|
|
||||||
return *_order.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<value_type>>& underlying() {
|
|
||||||
return _order;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename T2>
|
|
||||||
std::unique_ptr<T> erase_this(ptr_vec<T>& vec, T2* el)
|
|
||||||
{
|
|
||||||
return vec.erase(*el);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename T2>
|
|
||||||
std::unique_ptr<T> erase_this(ptr_vec<T>& vec, T2& el)
|
|
||||||
{
|
|
||||||
return vec.erase(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct non_null_ptr {
|
|
||||||
non_null_ptr() = delete;
|
|
||||||
constexpr non_null_ptr(T* ptr) : _ptr(ptr)
|
|
||||||
{
|
|
||||||
assert(ptr != nullptr);
|
|
||||||
}
|
|
||||||
non_null_ptr(std::nullptr_t) = delete;
|
|
||||||
|
|
||||||
constexpr non_null_ptr(const non_null_ptr&) = default;
|
|
||||||
constexpr non_null_ptr(non_null_ptr&&) = default;
|
|
||||||
constexpr non_null_ptr& operator=(const non_null_ptr&) = default;
|
|
||||||
constexpr non_null_ptr& operator=(non_null_ptr&&) = default;
|
|
||||||
|
|
||||||
constexpr T& operator*() const noexcept
|
|
||||||
{
|
|
||||||
return *_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr T* operator->() const noexcept
|
|
||||||
{
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr operator T*() noexcept
|
|
||||||
{
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr operator T* const() const noexcept
|
|
||||||
{
|
|
||||||
return _ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T* _ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct ref_vec {
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
std::vector<value_type*> _order;
|
|
||||||
|
|
||||||
using iterator = double_iterator<typename decltype(_order)::iterator>;
|
|
||||||
using const_iterator = double_iterator<typename decltype(_order)::const_iterator>;
|
|
||||||
|
|
||||||
using reverse_iterator = double_iterator<typename decltype(_order)::reverse_iterator>;
|
|
||||||
using const_reverse_iterator =
|
|
||||||
double_iterator<typename decltype(_order)::const_reverse_iterator>;
|
|
||||||
|
|
||||||
ref_vec() = default;
|
|
||||||
|
|
||||||
ref_vec(std::initializer_list<value_type*> lst) : _order {lst} { };
|
|
||||||
|
|
||||||
template<typename InputIter, typename = std::enable_if_t<std::is_same_v<decltype(*std::declval<InputIter>()), value_type&>>>
|
|
||||||
ref_vec(InputIter iter1, InputIter iter2) {
|
|
||||||
_order.reserve(std::distance(iter1, iter2));
|
|
||||||
std::transform(iter1, iter2, std::back_inserter(_order), [] (auto& v) {return &v; });
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Range, typename = std::enable_if_t<std::is_same_v<decltype(*std::declval<Range>().begin()), value_type&>>>
|
|
||||||
ref_vec(Range&& rng) : ref_vec (std::begin(rng), std::end(rng)) { }
|
|
||||||
|
|
||||||
value_type& push_back(value_type& v)
|
|
||||||
{
|
|
||||||
_order.push_back(&v);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& push_back(non_null_ptr<value_type> ptr)
|
|
||||||
{
|
|
||||||
_order.push_back(ptr);
|
|
||||||
return *ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& emplace_back(value_type& v)
|
|
||||||
{
|
|
||||||
return push_back(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<value_type> erase(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
auto uptr = std::move(*iter);
|
|
||||||
_order.erase(iter);
|
|
||||||
return uptr;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_back(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
|
|
||||||
return rotate_to_back(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_back(iterator iter)
|
|
||||||
{
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
{
|
|
||||||
return std::rotate(iter.data(), iter.data() + 1, _order.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_front(const value_type& v)
|
|
||||||
{
|
|
||||||
auto iter =
|
|
||||||
std::find_if(_order.begin(), _order.end(), [&v](auto&& ptr) { return ptr == &v; });
|
|
||||||
return rotate_to_front(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator rotate_to_front(iterator iter)
|
|
||||||
{
|
|
||||||
if (iter != _order.end()) {
|
|
||||||
{
|
|
||||||
return std::rotate(_order.begin(), iter.data(), iter.data() + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const noexcept
|
|
||||||
{
|
|
||||||
return _order.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const noexcept
|
|
||||||
{
|
|
||||||
return _order.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t capacity() const noexcept
|
|
||||||
{
|
|
||||||
return _order.capacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t max_size() const noexcept
|
|
||||||
{
|
|
||||||
return _order.max_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reserve(std::size_t new_cap)
|
|
||||||
{
|
|
||||||
_order.reserve(new_cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void shrink_to_fit()
|
|
||||||
{
|
|
||||||
_order.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& operator[](std::size_t n)
|
|
||||||
{
|
|
||||||
return *_order[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& operator[](std::size_t n) const
|
|
||||||
{
|
|
||||||
return *_order[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& at(std::size_t n)
|
|
||||||
{
|
|
||||||
return *_order.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& at(std::size_t n) const
|
|
||||||
{
|
|
||||||
return *_order.at(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return _order.begin();
|
|
||||||
}
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
return _order.end();
|
|
||||||
}
|
|
||||||
const_iterator begin() const
|
|
||||||
{
|
|
||||||
return _order.begin();
|
|
||||||
}
|
|
||||||
const_iterator end() const
|
|
||||||
{
|
|
||||||
return _order.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_iterator rbegin()
|
|
||||||
{
|
|
||||||
return _order.rbegin();
|
|
||||||
}
|
|
||||||
reverse_iterator rend()
|
|
||||||
{
|
|
||||||
return _order.rend();
|
|
||||||
}
|
|
||||||
const_reverse_iterator rbegin() const
|
|
||||||
{
|
|
||||||
return _order.rbegin();
|
|
||||||
}
|
|
||||||
const_reverse_iterator rend() const
|
|
||||||
{
|
|
||||||
return _order.rend();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& front()
|
|
||||||
{
|
|
||||||
return *_order.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
value_type& back()
|
|
||||||
{
|
|
||||||
return *_order.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& front() const
|
|
||||||
{
|
|
||||||
return *_order.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_type& back() const
|
|
||||||
{
|
|
||||||
return *_order.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<value_type*>& underlying() {
|
|
||||||
return _order;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace waybar::util
|
|
|
@ -42,6 +42,11 @@ window {
|
||||||
background-color: #26A65B;
|
background-color: #26A65B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.battery.warning {
|
||||||
|
background: #f53c3c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.cpu {
|
.cpu {
|
||||||
background: #2ecc71;
|
background: #2ecc71;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|
|
@ -49,7 +49,7 @@ void waybar::Client::_handle_global(void *data, struct wl_registry *registry,
|
||||||
auto output = std::make_unique<struct wl_output *>();
|
auto output = std::make_unique<struct wl_output *>();
|
||||||
*output = (struct wl_output *)wl_registry_bind(registry, name,
|
*output = (struct wl_output *)wl_registry_bind(registry, name,
|
||||||
&wl_output_interface, version);
|
&wl_output_interface, version);
|
||||||
o->bars.emplace_back(*o, std::move(output));
|
o->bars.emplace_back(std::make_unique<Bar>(*o, std::move(output)));
|
||||||
} else if (!strcmp(interface, wl_seat_interface.name)) {
|
} else if (!strcmp(interface, wl_seat_interface.name)) {
|
||||||
o->seat = (struct wl_seat *)wl_registry_bind(registry, name,
|
o->seat = (struct wl_seat *)wl_registry_bind(registry, name,
|
||||||
&wl_seat_interface, version);
|
&wl_seat_interface, version);
|
||||||
|
|
|
@ -15,7 +15,7 @@ int main(int argc, char* argv[])
|
||||||
waybar::client = &c;
|
waybar::client = &c;
|
||||||
std::signal(SIGUSR1, [] (int signal) {
|
std::signal(SIGUSR1, [] (int signal) {
|
||||||
for (auto& bar : waybar::client->bars) {
|
for (auto& bar : waybar::client->bars) {
|
||||||
bar.toggle();
|
bar.get()->toggle();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -42,14 +42,18 @@ auto waybar::modules::Battery::update() -> void
|
||||||
charging = true;
|
charging = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (charging) {
|
|
||||||
_label.get_style_context()->add_class("charging");
|
|
||||||
} else {
|
|
||||||
_label.get_style_context()->remove_class("charging");
|
|
||||||
}
|
|
||||||
auto format = _config["format"] ? _config["format"].asString() : "{}%";
|
auto format = _config["format"] ? _config["format"].asString() : "{}%";
|
||||||
_label.set_text(fmt::format(format, total / _batteries.size()));
|
auto value = total / _batteries.size();
|
||||||
|
_label.set_text(fmt::format(format, value));
|
||||||
_label.set_tooltip_text(charging ? "Charging" : "Discharging");
|
_label.set_tooltip_text(charging ? "Charging" : "Discharging");
|
||||||
|
if (charging)
|
||||||
|
_label.get_style_context()->add_class("charging");
|
||||||
|
else
|
||||||
|
_label.get_style_context()->remove_class("charging");
|
||||||
|
if (value < 52 && !charging)
|
||||||
|
_label.get_style_context()->add_class("warning");
|
||||||
|
else
|
||||||
|
_label.get_style_context()->remove_class("warning");
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue