Projects
Multimedia
ncmpc
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 15
View file
ncmpc.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Tue Sep 12 22:48:05 UTC 2023 - Muhammad Akbar Yanuar Mantari <mantarimay@pm.me> + +- Update to version 0.49 + +------------------------------------------------------------------- Fri May 12 05:43:37 UTC 2023 - Muhammad Akbar Yanuar Mantari <mantarimay@pm.me> - Update to version 0.48
View file
ncmpc.spec
Changed
@@ -17,7 +17,7 @@ Name: ncmpc -Version: 0.48 +Version: 0.49 Release: 0 Summary: Curses Client for the Music Player Daemon License: GPL-2.0-or-later
View file
ncmpc-0.48.tar.xz/NEWS -> ncmpc-0.49.tar.xz/NEWS
Changed
@@ -1,3 +1,8 @@ +ncmpc 0.49 - (2023-08-04) +* fix UI freeze if lyrics plugin is stuck +* fix missing tags with libmpdclient 2.21 +* fix build failure on macOS + ncmpc 0.48 - (2023-04-06) * drop support for ~/.ncmpc/; using only ~/.config/ncmpc/ (XDG) * improve scroll-offset handling
View file
ncmpc-0.48.tar.xz/doc/conf.py -> ncmpc-0.49.tar.xz/doc/conf.py
Changed
@@ -38,7 +38,7 @@ # built documents. # # The short X.Y version. -version = '0.48' +version = '0.49' # The full version, including alpha/beta/rc tags. release = version
View file
ncmpc-0.48.tar.xz/meson.build -> ncmpc-0.49.tar.xz/meson.build
Changed
@@ -1,5 +1,5 @@ project('ncmpc', 'cpp', - version: '0.48', + version: '0.49', meson_version: '>= 0.49', default_options: 'cpp_std=c++2a',
View file
ncmpc-0.48.tar.xz/src/ConfigFile.cxx -> ncmpc-0.49.tar.xz/src/ConfigFile.cxx
Changed
@@ -34,17 +34,22 @@ std::string MakeKeysPath() { - return MakeUserConfigPath(KEYS_FILENAME); + const auto dir = GetUserConfigDirectory(PACKAGE); + if (dir.empty()) + return {}; + + mkdir(dir.c_str(), 0777); + return BuildPath(dir, KEYS_FILENAME); } std::string GetUserConfigPath() noexcept { - const auto dir = GetHomeConfigDirectory(); + const auto dir = GetUserConfigDirectory(PACKAGE); if (dir.empty()) return {}; - return BuildPath(dir, PACKAGE, CONFIG_FILENAME); + return BuildPath(dir, CONFIG_FILENAME); } std::string @@ -65,30 +70,15 @@ #endif } -#ifndef _WIN32 - -gnu::pure -static std::string -GetHomeKeysPath() noexcept -{ - const char *home = GetHomeDirectory(); - if (home == nullptr) - return {}; - - return BuildPath(home, "." PACKAGE, KEYS_FILENAME); -} - -#endif - gnu::pure static std::string GetUserKeysPath() noexcept { - const auto dir = GetHomeConfigDirectory(); + const auto dir = GetUserConfigDirectory(PACKAGE); if (dir.empty()) return {}; - return BuildPath(dir, PACKAGE, KEYS_FILENAME); + return BuildPath(dir, KEYS_FILENAME); } gnu::pure @@ -142,13 +132,6 @@ if (!filename.empty() && IsFile(filename.c_str())) return filename; -#ifndef _WIN32 - /* check for user key bindings ~/.ncmpc/keys */ - filename = GetHomeKeysPath(); - if (!filename.empty() && IsFile(filename.c_str())) - return filename; -#endif - /* check for global key bindings SYSCONFDIR/ncmpc/keys */ filename = GetSystemKeysPath(); if (IsFile(filename.c_str()))
View file
ncmpc-0.48.tar.xz/src/KeyDefPage.cxx -> ncmpc-0.49.tar.xz/src/KeyDefPage.cxx
Changed
@@ -284,8 +284,6 @@ default: return false; } - - return false; } class CommandListPage final : public ListPage, ListText {
View file
ncmpc-0.48.tar.xz/src/LyricsCache.cxx -> ncmpc-0.49.tar.xz/src/LyricsCache.cxx
Changed
@@ -13,7 +13,7 @@ static std::string GetLyricsCacheDirectory() noexcept { - const auto ncmpc_cache_directory = GetHomeCacheDirectory(PACKAGE); + const auto ncmpc_cache_directory = GetUserCacheDirectory(PACKAGE); if (ncmpc_cache_directory.empty()) return {};
View file
ncmpc-0.48.tar.xz/src/TagMask.hxx -> ncmpc-0.49.tar.xz/src/TagMask.hxx
Changed
@@ -11,7 +11,11 @@ #include <stdint.h> class TagMask { - typedef uint_least32_t mask_t; + using mask_t = uint_least64_t; + + static_assert(sizeof(mask_t) * 8 >= MPD_TAG_COUNT, + "The mask does not have enough bits for the tags supported by MPD"); + mask_t value; explicit constexpr TagMask(uint_least32_t _value) noexcept
View file
ncmpc-0.48.tar.xz/src/XdgBaseDirectory.cxx -> ncmpc-0.49.tar.xz/src/XdgBaseDirectory.cxx
Changed
@@ -2,34 +2,26 @@ // Copyright The Music Player Daemon Project #include "XdgBaseDirectory.hxx" -#include "config.h" #include "io/Path.hxx" #include <stdlib.h> -#include <sys/stat.h> -gnu::pure -static bool -IsDirectory(const char *path) noexcept -{ - struct stat st; - return stat(path, &st) == 0 && S_ISDIR(st.st_mode); -} - -const char * -GetHomeDirectory() noexcept +gnu::const +static const char * +GetUserDirectory() noexcept { return getenv("HOME"); } -std::string -GetHomeConfigDirectory() noexcept +gnu::const +static std::string +GetUserConfigDirectory() noexcept { const char *config_home = getenv("XDG_CONFIG_HOME"); if (config_home != nullptr && *config_home != 0) return config_home; - const char *home = GetHomeDirectory(); + const char *home = GetUserDirectory(); if (home != nullptr) return BuildPath(home, ".config"); @@ -37,36 +29,24 @@ } std::string -GetHomeConfigDirectory(const char *package) noexcept +GetUserConfigDirectory(std::string_view package) noexcept { - const auto dir = GetHomeConfigDirectory(); + const auto dir = GetUserConfigDirectory(); if (dir.empty()) return {}; return BuildPath(dir, package); } -std::string -MakeUserConfigPath(const char *filename) noexcept -{ - const auto directory = GetHomeConfigDirectory(PACKAGE); - if (directory.empty()) - return {}; - - return IsDirectory(directory.c_str()) || - mkdir(directory.c_str(), 0755) == 0 - ? BuildPath(directory, filename) - : std::string(); -} - -std::string -GetHomeCacheDirectory() noexcept +gnu::const +static std::string +GetUserCacheDirectory() noexcept { const char *cache_home = getenv("XDG_CACHE_HOME"); if (cache_home != nullptr && *cache_home != 0) return cache_home; - const char *home = GetHomeDirectory(); + const char *home = GetUserDirectory(); if (home != nullptr) return BuildPath(home, ".cache"); @@ -74,9 +54,9 @@ } std::string -GetHomeCacheDirectory(const char *package) noexcept +GetUserCacheDirectory(std::string_view package) noexcept { - const auto dir = GetHomeCacheDirectory(); + const auto dir = GetUserCacheDirectory(); if (dir.empty()) return {};
View file
ncmpc-0.48.tar.xz/src/XdgBaseDirectory.hxx -> ncmpc-0.49.tar.xz/src/XdgBaseDirectory.hxx
Changed
@@ -1,38 +1,23 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef XDG_BASE_DIRECTORY_HXX -#define XDG_BASE_DIRECTORY_HXX +#pragma once #include <string> +#include <string_view> -gnu::const -const char * -GetHomeDirectory() noexcept; - -gnu::const -std::string -GetHomeConfigDirectory() noexcept; - +/** + * Returns the absolute path of the XDG config directory for the + * specified package (or an empty string on error). + */ gnu::pure std::string -GetHomeConfigDirectory(const char *package) noexcept; +GetUserConfigDirectory(std::string_view package) noexcept; /** - * Find or create the directory for writing configuration files. - * - * @return the absolute path; an empty string indicates that no - * directory could be created + * Returns the absolute path of the XDG cache directory for the + * specified package (or an empty string on error). */ -std::string -MakeUserConfigPath(const char *filename) noexcept; - -gnu::const -std::string -GetHomeCacheDirectory() noexcept; - gnu::pure std::string -GetHomeCacheDirectory(const char *package) noexcept; - -#endif +GetUserCacheDirectory(std::string_view package) noexcept;
View file
ncmpc-0.48.tar.xz/src/event/Loop.cxx -> ncmpc-0.49.tar.xz/src/event/Loop.cxx
Changed
@@ -275,10 +275,8 @@ #endif assert(IsInside()); - assert(!quit); #ifdef HAVE_THREADED_EVENT_LOOP - assert(!quit_injected); - assert(alive); + assert(alive || quit_injected); assert(busy); wake_event.Schedule(SocketEvent::READ); @@ -303,7 +301,7 @@ FlushClockCaches(); - do { + while (!quit) { again = false; /* invoke timers */ @@ -365,7 +363,7 @@ socket_event.Dispatch(); } - } while (!quit); + } #ifdef HAVE_THREADED_EVENT_LOOP #ifndef NDEBUG
View file
ncmpc-0.48.tar.xz/src/io/Path.hxx -> ncmpc-0.49.tar.xz/src/io/Path.hxx
Changed
@@ -5,8 +5,7 @@ #define IO_PATH_HXX #include <string> - -#include <string.h> +#include <string_view> namespace PathDetail { @@ -16,93 +15,37 @@ static constexpr char SEPARATOR = '/'; #endif -gnu::pure -inline size_t -GetLength(const char *s) noexcept -{ - return strlen(s); -} - -gnu::pure -inline size_t -GetLength(const std::string &s) noexcept +inline void +AppendWithSeparator(std::string &dest, std::string_view src) noexcept { - return s.length(); + dest.push_back(SEPARATOR); + dest.append(src); } template<typename... Args> -inline size_t -FillLengths(size_t *lengths, Args&&... args) noexcept; - -template<typename First, typename... Args> -inline size_t -FillLengths(size_t *lengths, First &&first, Args&&... args) noexcept -{ - size_t length = GetLength(std::forward<First>(first)); - *lengths++ = length; - return length + FillLengths(lengths, std::forward<Args>(args)...); -} - -template<> -inline size_t -FillLengths(size_t *) noexcept -{ - return 0; -} - -inline std::string & -Append(std::string &dest, const std::string &value, size_t length) noexcept +std::string +BuildPath(std::string_view first, Args&&... args) noexcept { - return dest.append(value, 0, length); -} + constexpr size_t n = sizeof...(args); -inline std::string & -Append(std::string &dest, const char *value, size_t length) noexcept -{ - return dest.append(value, length); -} + const std::size_t total = first.size() + (args.size() + ...); -template<typename... Args> -inline std::string & -AppendWithSeparators(std::string &dest, const size_t *lengths, - Args&&... args) noexcept; + std::string result; + result.reserve(total + n); -template<typename First, typename... Args> -inline std::string & -AppendWithSeparators(std::string &dest, const size_t *lengths, - First &&first, Args&&... args) noexcept -{ - dest.push_back(SEPARATOR); - return AppendWithSeparators(Append(dest, std::forward<First>(first), - *lengths), - lengths + 1, - std::forward<Args>(args)...); -} + result.append(first); + (AppendWithSeparator(result, args), ...); -template<> -inline std::string & -AppendWithSeparators(std::string &dest, const size_t *) noexcept -{ - return dest; + return result; } } // namespace PathDetail -template<typename First, typename... Args> +template<typename... Args> std::string -BuildPath(First &&first, Args&&... args) noexcept +BuildPath(std::string_view first, Args&&... args) noexcept { - constexpr size_t n = sizeof...(args); - - size_t lengthsn + 1; - const size_t total = PathDetail::FillLengths(lengths, first, args...); - - std::string result; - result.reserve(total + n); - PathDetail::Append(result, std::forward<First>(first), lengths0); - PathDetail::AppendWithSeparators(result, lengths + 1, - std::forward<Args>(args)...); - return result; + return PathDetail::BuildPath(first, static_cast<std::string_view>(args)...); } #endif
View file
ncmpc-0.48.tar.xz/src/plugin.cxx -> ncmpc-0.49.tar.xz/src/plugin.cxx
Changed
@@ -6,6 +6,7 @@ #include "io/UniqueFileDescriptor.hxx" #include "event/PipeEvent.hxx" #include "event/CoarseTimerEvent.hxx" +#include "event/Features.h" // for USE_SIGNALFD #include "util/ScopeExit.hxx" #include "util/UriUtil.hxx" @@ -21,6 +22,10 @@ #include <sys/stat.h> #include <sys/wait.h> +#ifdef __APPLE__ +extern char **environ; +#endif + struct PluginCycle; class PluginPipe { @@ -259,7 +264,15 @@ posix_spawn_file_actions_adddup2(&file_actions, stderr_w.Get(), STDERR_FILENO); - if (posix_spawn(&pid, plugin_path, &file_actions, nullptr, + posix_spawnattr_t attr; + posix_spawnattr_init(&attr); + +#ifdef USE_SIGNALFD + /* unblock all signals which may be blocked for signalfd */ + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK); +#endif + + if (posix_spawn(&pid, plugin_path, &file_actions, &attr, argv.get(), environ) != 0) return -1;
View file
ncmpc-0.48.tar.xz/src/system/Error.hxx -> ncmpc-0.49.tar.xz/src/system/Error.hxx
Changed
@@ -6,23 +6,10 @@ #include <system_error> // IWYU pragma: export #include <utility> -#include <stdio.h> - -template<typename... Args> -static inline std::system_error -FormatSystemError(std::error_code code, const char *fmt, - Args&&... args) noexcept -{ - char buffer1024; - snprintf(buffer, sizeof(buffer), fmt, std::forward<Args>(args)...); - return std::system_error(code, buffer); -} - #ifdef _WIN32 #include <errhandlingapi.h> // for GetLastError() -#include <windef.h> // for HWND (needed by winbase.h) -#include <winbase.h> // for FormatMessageA() +#include <winerror.h> /** * Returns the error_category to be used to wrap WIN32 GetLastError() @@ -59,38 +46,10 @@ return MakeLastError(GetLastError(), msg); } -template<typename... Args> -static inline std::system_error -FormatLastError(DWORD code, const char *fmt, Args&&... args) noexcept -{ - char buffer512; - const auto end = buffer + sizeof(buffer); - size_t length = snprintf(buffer, sizeof(buffer) - 128, - fmt, std::forward<Args>(args)...); - char *p = buffer + length; - *p++ = ':'; - *p++ = ' '; - - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, code, 0, p, end - p, nullptr); - return MakeLastError(code, buffer); -} - -template<typename... Args> -static inline std::system_error -FormatLastError(const char *fmt, Args&&... args) noexcept -{ - return FormatLastError(GetLastError(), fmt, - std::forward<Args>(args)...); -} - #endif /* _WIN32 */ #include <cerrno> // IWYU pragma: export -#include <string.h> - /** * Returns the error_category to be used to wrap errno values. The * C++ standard does not define this well, so this code is based on @@ -127,35 +86,6 @@ return MakeErrno(errno, msg); } -template<typename... Args> -static inline std::system_error -FormatErrno(int code, const char *fmt, Args&&... args) noexcept -{ - char buffer512; - snprintf(buffer, sizeof(buffer), - fmt, std::forward<Args>(args)...); - return MakeErrno(code, buffer); -} - -template<typename... Args> -static inline std::system_error -FormatErrno(const char *fmt, Args&&... args) noexcept -{ - return FormatErrno(errno, fmt, std::forward<Args>(args)...); -} - -template<typename... Args> -static inline std::system_error -FormatFileNotFound(const char *fmt, Args&&... args) noexcept -{ -#ifdef _WIN32 - return FormatLastError(ERROR_FILE_NOT_FOUND, fmt, - std::forward<Args>(args)...); -#else - return FormatErrno(ENOENT, fmt, std::forward<Args>(args)...); -#endif -} - gnu::pure inline bool IsErrno(const std::system_error &e, int code) noexcept
View file
ncmpc-0.48.tar.xz/src/util/Concepts.hxx -> ncmpc-0.49.tar.xz/src/util/Concepts.hxx
Changed
@@ -5,33 +5,5 @@ #include <concepts> -/** - * Compatibility wrapper for std::invocable which is unavailable in - * the Android NDK r25b and Apple Xcode. - */ -#if !defined(ANDROID) && !defined(__APPLE__) -template<typename F, typename... Args> -concept Invocable = std::invocable<F, Args...>; -#else -template<typename F, typename... Args> -concept Invocable = requires(F f, Args... args) { - { f(args...) }; -}; -#endif - -/** - * Compatibility wrapper for std::predicate which is unavailable in - * the Android NDK r25b and Apple Xcode. - */ -#if !defined(ANDROID) && !defined(__APPLE__) -template<typename F, typename... Args> -concept Predicate = std::predicate<F, Args...>; -#else -template<typename F, typename... Args> -concept Predicate = requires(F f, Args... args) { - { f(args...) } -> std::same_as<bool>; -}; -#endif - template<typename F, typename T> -concept Disposer = Invocable<F, T *>; +concept Disposer = std::invocable<F, T *>;
View file
ncmpc-0.48.tar.xz/src/util/IntrusiveList.hxx -> ncmpc-0.49.tar.xz/src/util/IntrusiveList.hxx
Changed
@@ -78,30 +78,25 @@ IntrusiveListHook<IntrusiveHookMode::AUTO_UNLINK>; /** - * Detect the hook type which is embedded in the given type as a base - * class. This is a template to postpone the type checks, to allow - * forward-declared types. - */ -template<typename U> -struct IntrusiveListHookDetection { - /* TODO can this be simplified somehow, without checking for - all possible enum values? */ - using type = std::conditional_t<std::is_base_of_v<IntrusiveListHook<IntrusiveHookMode::NORMAL>, U>, - IntrusiveListHook<IntrusiveHookMode::NORMAL>, - std::conditional_t<std::is_base_of_v<IntrusiveListHook<IntrusiveHookMode::TRACK>, U>, - IntrusiveListHook<IntrusiveHookMode::TRACK>, - std::conditional_t<std::is_base_of_v<IntrusiveListHook<IntrusiveHookMode::AUTO_UNLINK>, U>, - IntrusiveListHook<IntrusiveHookMode::AUTO_UNLINK>, - void>>>; -}; - -/** * For classes which embed #IntrusiveListHook as base class. */ template<typename T> struct IntrusiveListBaseHookTraits { + /* a never-called helper function which is used by _Cast() */ + template<IntrusiveHookMode mode> + static constexpr IntrusiveListHook<mode> _Identity(const IntrusiveListHook<mode> &) noexcept; + + /* another never-called helper function which "calls" + _Identity(), implicitly casting the item to the + IntrusiveListHook specialization; we use this to detect + which IntrusiveListHook specialization is used */ + template<typename U> + static constexpr auto _Cast(const U &u) noexcept { + return decltype(_Identity(u))(); + } + template<typename U> - using Hook = typename IntrusiveListHookDetection<U>::type; + using Hook = decltype(_Cast(std::declval<U>())); static constexpr T *Cast(IntrusiveListNode *node) noexcept { auto *hook = &Hook<T>::Cast(*node); @@ -264,16 +259,14 @@ void clear_and_dispose(Disposer<value_type> auto disposer) noexcept { while (!empty()) { - auto *item = &front(); - pop_front(); - disposer(item); + disposer(&pop_front()); } } /** * @return the number of removed items */ - std::size_t remove_and_dispose_if(Predicate<const_reference> auto pred, + std::size_t remove_and_dispose_if(std::predicate<const_reference> auto pred, Disposer<value_type> auto dispose) noexcept { std::size_t result = 0; @@ -302,15 +295,15 @@ return *Cast(head.next); } - void pop_front() noexcept { - ToHook(front()).unlink(); + reference pop_front() noexcept { + auto &i = front(); + ToHook(i).unlink(); --counter; + return i; } void pop_front_and_dispose(Disposer<value_type> auto disposer) noexcept { - auto &i = front(); - ToHook(i).unlink(); - --counter; + auto &i = pop_front(); disposer(&i); } @@ -319,7 +312,8 @@ } void pop_back() noexcept { - ToHook(back()).unlink(); + auto &i = back(); + ToHook(i).unlink(); --counter; } @@ -487,12 +481,18 @@ insert(end(), t); } + /** + * Insert a new item before the given position. + * + * @param p a valid iterator (end() is allowed)for this list + * describing the position where to insert + */ void insert(iterator p, reference t) noexcept { static_assert(!constant_time_size || GetHookMode() < IntrusiveHookMode::AUTO_UNLINK, "Can't use auto-unlink hooks with constant_time_size"); - auto &existing_node = ToNode(*p); + auto &existing_node = *p.cursor; auto &new_node = ToNode(t); IntrusiveListNode::Connect(*existing_node.prev, @@ -503,6 +503,13 @@ } /** + * Like insert(), but insert after the given position. + */ + void insert_after(iterator p, reference t) noexcept { + insert(std::next(p), t); + } + + /** * Move one item of the given list to this one before the * given position. */ @@ -522,13 +529,13 @@ if (_begin == _end) return; - auto &next_node = ToNode(*position); - auto &prev_node = ToNode(*std::prev(position)); + auto &next_node = *position.cursor; + auto &prev_node = *std::prev(position).cursor; - auto &first_node = ToNode(*_begin); - auto &before_first_node = ToNode(*std::prev(_begin)); - auto &last_node = ToNode(*std::prev(_end)); - auto &after_last_node = ToNode(*_end); + auto &first_node = *_begin.cursor; + auto &before_first_node = *std::prev(_begin).cursor; + auto &last_node = *std::prev(_end).cursor; + auto &after_last_node = *_end.cursor; /* remove from the other list */ IntrusiveListNode::Connect(before_first_node, after_last_node);
View file
ncmpc-0.48.tar.xz/src/util/ScopeExit.hxx -> ncmpc-0.49.tar.xz/src/util/ScopeExit.hxx
Changed
@@ -10,20 +10,27 @@ * Internal class. Do not use directly. */ template<typename F> -class ScopeExitGuard : F { +class ScopeExitGuard { + no_unique_address + F function; + bool enabled = true; public: - explicit ScopeExitGuard(F &&f):F(std::forward<F>(f)) {} + explicit ScopeExitGuard(F &&f) noexcept + :function(std::forward<F>(f)) {} - ScopeExitGuard(ScopeExitGuard &&src) - :F(std::move(src)), enabled(src.enabled) { - src.enabled = false; - } + ScopeExitGuard(ScopeExitGuard &&src) noexcept + :function(std::move(src.function)), + enabled(std::exchange(src.enabled, false)) {} - ~ScopeExitGuard() { + /* destructors are "noexcept" by default; this explicit + "noexcept" declaration allows the destructor to throw if + the function can throw; without this, a throwing function + would std::terminate() */ + ~ScopeExitGuard() noexcept(noexcept(std::declval<F>()())) { if (enabled) - F::operator()(); + function(); } ScopeExitGuard(const ScopeExitGuard &) = delete; @@ -38,7 +45,7 @@ parantheses at the end of the expression AtScopeExit() call */ template<typename F> - ScopeExitGuard<F> operator+(F &&f) { + ScopeExitGuard<F> operator+(F &&f) noexcept { return ScopeExitGuard<F>(std::forward<F>(f)); } };
View file
ncmpc-0.48.tar.xz/src/util/SortList.hxx -> ncmpc-0.49.tar.xz/src/util/SortList.hxx
Changed
@@ -3,10 +3,10 @@ #pragma once -#include "Concepts.hxx" #include "StaticVector.hxx" #include <algorithm> // for std::find_if() +#include <concepts> /** * Move all items from #src to #dest, keeping both sorted. @@ -17,7 +17,7 @@ template<typename List> constexpr void MergeList(List &dest, List &src, - Predicate<typename List::const_reference, typename List::const_reference> auto p) noexcept + std::predicate<typename List::const_reference, typename List::const_reference> auto p) noexcept { const auto dest_end = dest.end(), src_end = src.end(); @@ -59,7 +59,7 @@ template<typename List> constexpr void SortList(List &list, - Predicate <typename List::const_reference, typename List::const_reference> auto p) noexcept + std::predicate <typename List::const_reference, typename List::const_reference> auto p) noexcept { using std::swap;
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.