1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2018 The Music Player Daemon Project
3 * Project homepage: http://musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 namespace PathDetail {
32 static constexpr char SEPARATOR = '\\';
34 static constexpr char SEPARATOR = '/';
39 GetLength(const char *s) noexcept
46 GetLength(const std::string &s) noexcept
51 template<typename... Args>
53 FillLengths(size_t *lengths, Args&&... args) noexcept;
55 template<typename First, typename... Args>
57 FillLengths(size_t *lengths, First &&first, Args&&... args) noexcept
59 size_t length = GetLength(std::forward<First>(first));
61 return length + FillLengths(lengths, std::forward<Args>(args)...);
66 FillLengths(size_t *) noexcept
72 Append(std::string &dest, const std::string &value, size_t length) noexcept
74 return dest.append(value, 0, length);
78 Append(std::string &dest, const char *value, size_t length) noexcept
80 return dest.append(value, length);
83 template<typename... Args>
85 AppendWithSeparators(std::string &dest, const size_t *lengths,
86 Args&&... args) noexcept;
88 template<typename First, typename... Args>
90 AppendWithSeparators(std::string &dest, const size_t *lengths,
91 First &&first, Args&&... args) noexcept
93 dest.push_back(SEPARATOR);
94 return AppendWithSeparators(Append(dest, std::forward<First>(first),
97 std::forward<Args>(args)...);
102 AppendWithSeparators(std::string &dest, const size_t *) noexcept
107 } // namespace PathDetail
109 template<typename First, typename... Args>
111 BuildPath(First &&first, Args&&... args) noexcept
113 constexpr size_t n = sizeof...(args);
115 size_t lengths[n + 1];
116 const size_t total = PathDetail::FillLengths(lengths, first, args...);
119 result.reserve(total + n);
120 PathDetail::Append(result, std::forward<First>(first), lengths[0]);
121 PathDetail::AppendWithSeparators(result, lengths + 1,
122 std::forward<Args>(args)...);