| @@ -6,6 +6,9 @@ | |||
| #include <dds/project.hpp> | |||
| #include <dds/source.hpp> | |||
| #include <dds/toolchain.hpp> | |||
| #include <dds/util/algo.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <dds/util/tl.hpp> | |||
| #include <libman/index.hpp> | |||
| #include <libman/parse.hpp> | |||
| @@ -3,7 +3,7 @@ | |||
| #include <dds/package_manifest.hpp> | |||
| #include <dds/toolchain.hpp> | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <optional> | |||
| @@ -1,6 +1,7 @@ | |||
| #include "./compile.hpp" | |||
| #include <dds/proc.hpp> | |||
| #include <dds/util/algo.hpp> | |||
| #include <spdlog/spdlog.h> | |||
| @@ -2,7 +2,7 @@ | |||
| #include <dds/source.hpp> | |||
| #include <dds/toolchain.hpp> | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <memory> | |||
| #include <optional> | |||
| @@ -1,7 +1,7 @@ | |||
| #include <dds/build.hpp> | |||
| #include <dds/logging.hpp> | |||
| #include <dds/sdist.hpp> | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <libman/parse.hpp> | |||
| @@ -1,5 +1,7 @@ | |||
| #include <dds/library.hpp> | |||
| #include <dds/util/algo.hpp> | |||
| #include <spdlog/spdlog.h> | |||
| using namespace dds; | |||
| @@ -1,6 +1,8 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <vector> | |||
| namespace dds { | |||
| @@ -1,6 +1,6 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <string> | |||
| @@ -1,6 +1,6 @@ | |||
| #include "./proc.hpp" | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <algorithm> | |||
| #include <array> | |||
| @@ -1,6 +1,7 @@ | |||
| #include <dds/project.hpp> | |||
| #include <dds/source.hpp> | |||
| #include <dds/util/tl.hpp> | |||
| #include <range/v3/range/conversion.hpp> | |||
| #include <range/v3/view/filter.hpp> | |||
| @@ -2,7 +2,7 @@ | |||
| #include <dds/library.hpp> | |||
| #include <dds/package_manifest.hpp> | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <optional> | |||
| #include <vector> | |||
| @@ -2,6 +2,8 @@ | |||
| #include <dds/project.hpp> | |||
| #include <dds/temp.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <dds/util/tl.hpp> | |||
| #include <libman/parse.hpp> | |||
| @@ -1,6 +1,6 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| namespace dds { | |||
| @@ -1,5 +1,8 @@ | |||
| #include "./source.hpp" | |||
| #include <dds/util/tl.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <spdlog/spdlog.h> | |||
| #include <range/v3/range/conversion.hpp> | |||
| @@ -1,6 +1,7 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <optional> | |||
| #include <vector> | |||
| @@ -1,6 +1,6 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <memory> | |||
| @@ -1,5 +1,8 @@ | |||
| #include "./toolchain.hpp" | |||
| #include <dds/util/algo.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <libman/parse.hpp> | |||
| #include <spdlog/fmt/fmt.h> | |||
| @@ -1,7 +1,7 @@ | |||
| #ifndef DDS_TOOLCHAIN_HPP_INCLUDED | |||
| #define DDS_TOOLCHAIN_HPP_INCLUDED | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <optional> | |||
| #include <string> | |||
| @@ -1,162 +0,0 @@ | |||
| #ifndef DDS_UTIL_HPP_INCLUDED | |||
| #define DDS_UTIL_HPP_INCLUDED | |||
| #include <algorithm> | |||
| #include <cctype> | |||
| #include <filesystem> | |||
| #include <fstream> | |||
| namespace dds { | |||
| namespace detail { | |||
| template <std::size_t I, | |||
| typename A = std::nullptr_t, | |||
| typename B = std::nullptr_t, | |||
| typename C = std::nullptr_t, | |||
| typename D = std::nullptr_t> | |||
| decltype(auto) nth_arg(A&& a = nullptr, B&& b = nullptr, C&& c = nullptr, D&& d = nullptr) { | |||
| if constexpr (I == 0) { | |||
| return (A &&) a; | |||
| } else if constexpr (I == 1) { | |||
| return (B &&) b; | |||
| } else if constexpr (I == 2) { | |||
| return (C &&) c; | |||
| } else if constexpr (I == 3) { | |||
| return (D &&) d; | |||
| } | |||
| } | |||
| } // namespace detail | |||
| // Based on https://github.com/Quincunx271/TerseLambda | |||
| #define DDS_CTL(...) \ | |||
| (auto&&... _args_)->auto { \ | |||
| [[maybe_unused]] auto&& _1 = ::dds::detail::nth_arg<0>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _2 = ::dds::detail::nth_arg<1>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _3 = ::dds::detail::nth_arg<2>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _4 = ::dds::detail::nth_arg<3>((decltype(_args_)&&)(_args_)...); \ | |||
| static_assert(sizeof...(_args_) <= 4); \ | |||
| return (__VA_ARGS__); \ | |||
| } | |||
| #define DDS_TL [&] DDS_CTL | |||
| inline namespace file_utils { | |||
| namespace fs = std::filesystem; | |||
| using path_ref = const fs::path&; | |||
| std::fstream open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec); | |||
| std::string slurp_file(const fs::path& path, std::error_code& ec); | |||
| inline std::fstream open(const fs::path& filepath, std::ios::openmode mode) { | |||
| std::error_code ec; | |||
| auto ret = dds::open(filepath, mode, ec); | |||
| if (ec) { | |||
| throw std::system_error{ec, "Error opening file: " + filepath.string()}; | |||
| } | |||
| return ret; | |||
| } | |||
| inline std::string slurp_file(const fs::path& path) { | |||
| std::error_code ec; | |||
| auto contents = dds::slurp_file(path, ec); | |||
| if (ec) { | |||
| throw std::system_error{ec, "Reading file: " + path.string()}; | |||
| } | |||
| return contents; | |||
| } | |||
| void safe_rename(path_ref source, path_ref dest); | |||
| } // namespace file_utils | |||
| template <typename Container, typename Predicate> | |||
| void erase_if(Container& c, Predicate&& p) { | |||
| auto erase_point = std::remove_if(c.begin(), c.end(), p); | |||
| c.erase(erase_point, c.end()); | |||
| } | |||
| template <typename Container, typename Other> | |||
| void extend(Container& c, const Other& o) { | |||
| c.insert(c.end(), o.begin(), o.end()); | |||
| } | |||
| template <typename Container, typename Item> | |||
| void extend(Container& c, std::initializer_list<Item> il) { | |||
| c.insert(c.end(), il.begin(), il.end()); | |||
| } | |||
| inline namespace string_utils { | |||
| inline std::string_view sview(std::string_view::const_iterator beg, | |||
| std::string_view::const_iterator end) { | |||
| return std::string_view(&*beg, static_cast<std::size_t>(std::distance(beg, end))); | |||
| } | |||
| inline std::string_view trim(std::string_view s) { | |||
| auto iter = s.begin(); | |||
| auto end = s.end(); | |||
| while (iter != end && std::isspace(*iter)) { | |||
| ++iter; | |||
| } | |||
| auto riter = s.rbegin(); | |||
| auto rend = s.rend(); | |||
| while (riter != rend && std::isspace(*riter)) { | |||
| ++riter; | |||
| } | |||
| auto new_end = riter.base(); | |||
| return sview(iter, new_end); | |||
| } | |||
| inline std::string trim(std::string&& s) { return std::string(trim(s)); } | |||
| inline bool ends_with(std::string_view s, std::string_view key) { | |||
| auto found = s.rfind(key); | |||
| return found != s.npos && found == s.size() - key.size(); | |||
| } | |||
| inline bool starts_with(std::string_view s, std::string_view key) { return s.find(key) == 0; } | |||
| inline bool contains(std::string_view s, std::string_view key) { return s.find(key) != s.npos; } | |||
| inline std::vector<std::string> split(std::string_view str, std::string_view sep) { | |||
| std::vector<std::string> ret; | |||
| std::string_view::size_type prev_pos = 0; | |||
| auto pos = prev_pos; | |||
| while ((pos = str.find(sep, prev_pos)) != str.npos) { | |||
| ret.emplace_back(str.substr(prev_pos, pos - prev_pos)); | |||
| prev_pos = pos + sep.length(); | |||
| } | |||
| ret.emplace_back(str.substr(prev_pos)); | |||
| return ret; | |||
| } | |||
| inline std::string replace(std::string_view str, std::string_view key, std::string_view repl) { | |||
| std::string ret; | |||
| std::string_view::size_type pos = 0; | |||
| std::string_view::size_type prev_pos = 0; | |||
| while (pos = str.find(key, pos), pos != key.npos) { | |||
| ret.append(str.begin() + prev_pos, str.begin() + pos); | |||
| ret.append(repl); | |||
| prev_pos = pos += key.size(); | |||
| } | |||
| ret.append(str.begin() + prev_pos, str.end()); | |||
| return ret; | |||
| } | |||
| inline std::vector<std::string> | |||
| replace(std::vector<std::string> strings, std::string_view key, std::string_view repl) { | |||
| for (auto& item : strings) { | |||
| item = replace(item, key, repl); | |||
| } | |||
| return strings; | |||
| } | |||
| } // namespace string_utils | |||
| } // namespace dds | |||
| #endif // DDS_UTIL_HPP_INCLUDED | |||
| @@ -0,0 +1,24 @@ | |||
| #pragma once | |||
| #include <algorithm> | |||
| #include <initializer_list> | |||
| namespace dds { | |||
| template <typename Container, typename Predicate> | |||
| void erase_if(Container& c, Predicate&& p) { | |||
| auto erase_point = std::remove_if(c.begin(), c.end(), p); | |||
| c.erase(erase_point, c.end()); | |||
| } | |||
| template <typename Container, typename Other> | |||
| void extend(Container& c, const Other& o) { | |||
| c.insert(c.end(), o.begin(), o.end()); | |||
| } | |||
| template <typename Container, typename Item> | |||
| void extend(Container& c, std::initializer_list<Item> il) { | |||
| c.insert(c.end(), il.begin(), il.end()); | |||
| } | |||
| } // namespace dds | |||
| @@ -1,11 +1,7 @@ | |||
| #include "./util.hpp" | |||
| #include "./fs.hpp" | |||
| #include <spdlog/fmt/fmt.h> | |||
| #include <filesystem> | |||
| #include <fstream> | |||
| #include <sstream> | |||
| using namespace dds; | |||
| std::fstream dds::open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec) { | |||
| @@ -0,0 +1,41 @@ | |||
| #pragma once | |||
| #include <filesystem> | |||
| #include <fstream> | |||
| #include <string> | |||
| #include <system_error> | |||
| namespace dds { | |||
| inline namespace file_utils { | |||
| namespace fs = std::filesystem; | |||
| using path_ref = const fs::path&; | |||
| std::fstream open(const fs::path& filepath, std::ios::openmode mode, std::error_code& ec); | |||
| std::string slurp_file(const fs::path& path, std::error_code& ec); | |||
| inline std::fstream open(const fs::path& filepath, std::ios::openmode mode) { | |||
| std::error_code ec; | |||
| auto ret = dds::open(filepath, mode, ec); | |||
| if (ec) { | |||
| throw std::system_error{ec, "Error opening file: " + filepath.string()}; | |||
| } | |||
| return ret; | |||
| } | |||
| inline std::string slurp_file(const fs::path& path) { | |||
| std::error_code ec; | |||
| auto contents = dds::slurp_file(path, ec); | |||
| if (ec) { | |||
| throw std::system_error{ec, "Reading file: " + path.string()}; | |||
| } | |||
| return contents; | |||
| } | |||
| void safe_rename(path_ref source, path_ref dest); | |||
| } // namespace file_utils | |||
| } // namespace dds | |||
| @@ -0,0 +1,78 @@ | |||
| #pragma once | |||
| #include <algorithm> | |||
| #include <string> | |||
| #include <string_view> | |||
| #include <vector> | |||
| namespace dds { | |||
| inline namespace string_utils { | |||
| inline std::string_view sview(std::string_view::const_iterator beg, | |||
| std::string_view::const_iterator end) { | |||
| return std::string_view(&*beg, static_cast<std::size_t>(std::distance(beg, end))); | |||
| } | |||
| inline std::string_view trim(std::string_view s) { | |||
| auto iter = s.begin(); | |||
| auto end = s.end(); | |||
| while (iter != end && std::isspace(*iter)) { | |||
| ++iter; | |||
| } | |||
| auto riter = s.rbegin(); | |||
| auto rend = s.rend(); | |||
| while (riter != rend && std::isspace(*riter)) { | |||
| ++riter; | |||
| } | |||
| auto new_end = riter.base(); | |||
| return sview(iter, new_end); | |||
| } | |||
| inline std::string trim(std::string&& s) { return std::string(trim(s)); } | |||
| inline bool ends_with(std::string_view s, std::string_view key) { | |||
| auto found = s.rfind(key); | |||
| return found != s.npos && found == s.size() - key.size(); | |||
| } | |||
| inline bool starts_with(std::string_view s, std::string_view key) { return s.find(key) == 0; } | |||
| inline bool contains(std::string_view s, std::string_view key) { return s.find(key) != s.npos; } | |||
| inline std::vector<std::string> split(std::string_view str, std::string_view sep) { | |||
| std::vector<std::string> ret; | |||
| std::string_view::size_type prev_pos = 0; | |||
| auto pos = prev_pos; | |||
| while ((pos = str.find(sep, prev_pos)) != str.npos) { | |||
| ret.emplace_back(str.substr(prev_pos, pos - prev_pos)); | |||
| prev_pos = pos + sep.length(); | |||
| } | |||
| ret.emplace_back(str.substr(prev_pos)); | |||
| return ret; | |||
| } | |||
| inline std::string replace(std::string_view str, std::string_view key, std::string_view repl) { | |||
| std::string ret; | |||
| std::string_view::size_type pos = 0; | |||
| std::string_view::size_type prev_pos = 0; | |||
| while (pos = str.find(key, pos), pos != key.npos) { | |||
| ret.append(str.begin() + prev_pos, str.begin() + pos); | |||
| ret.append(repl); | |||
| prev_pos = pos += key.size(); | |||
| } | |||
| ret.append(str.begin() + prev_pos, str.end()); | |||
| return ret; | |||
| } | |||
| inline std::vector<std::string> | |||
| replace(std::vector<std::string> strings, std::string_view key, std::string_view repl) { | |||
| for (auto& item : strings) { | |||
| item = replace(item, key, repl); | |||
| } | |||
| return strings; | |||
| } | |||
| } // namespace string_utils | |||
| } // namespace dds | |||
| @@ -1,4 +1,5 @@ | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/string.hpp> | |||
| #include <dds/util.test.hpp> | |||
| using namespace dds; | |||
| @@ -0,0 +1,41 @@ | |||
| #pragma once | |||
| #include <cstddef> | |||
| namespace dds { | |||
| namespace detail { | |||
| template <std::size_t I, | |||
| typename A = std::nullptr_t, | |||
| typename B = std::nullptr_t, | |||
| typename C = std::nullptr_t, | |||
| typename D = std::nullptr_t> | |||
| decltype(auto) nth_arg(A&& a = nullptr, B&& b = nullptr, C&& c = nullptr, D&& d = nullptr) { | |||
| if constexpr (I == 0) { | |||
| return (A &&) a; | |||
| } else if constexpr (I == 1) { | |||
| return (B &&) b; | |||
| } else if constexpr (I == 2) { | |||
| return (C &&) c; | |||
| } else if constexpr (I == 3) { | |||
| return (D &&) d; | |||
| } | |||
| } | |||
| } // namespace detail | |||
| // Based on https://github.com/Quincunx271/TerseLambda | |||
| #define DDS_CTL(...) \ | |||
| (auto&&... _args_)->auto { \ | |||
| [[maybe_unused]] auto&& _1 = ::dds::detail::nth_arg<0>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _2 = ::dds::detail::nth_arg<1>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _3 = ::dds::detail::nth_arg<2>((decltype(_args_)&&)(_args_)...); \ | |||
| [[maybe_unused]] auto&& _4 = ::dds::detail::nth_arg<3>((decltype(_args_)&&)(_args_)...); \ | |||
| static_assert(sizeof...(_args_) <= 4); \ | |||
| return (__VA_ARGS__); \ | |||
| } | |||
| #define DDS_TL [&] DDS_CTL | |||
| } // namespace dds | |||
| @@ -1,6 +1,7 @@ | |||
| #pragma once | |||
| #include <dds/util.hpp> | |||
| #include <dds/util/fs.hpp> | |||
| #include <dds/util/string.hpp> | |||
| namespace lm { | |||