14 #include <string_view> 19 #include <hilti/rt/exception.h> 20 #include <hilti/rt/filesystem.h> 21 #include <hilti/rt/result.h> 22 #include <hilti/rt/types/set_fwd.h> 23 #include <hilti/rt/types/time.h> 24 #include <hilti/rt/types/vector_fwd.h> 38 #define HILTI_RT_ENUM_WITH_DEFAULT(name, default_, ...) \ 40 enum Value : int64_t { __VA_ARGS__ }; \ 41 constexpr name(int64_t value = default_) noexcept : _value(value) {} \ 42 friend name Enum(Value value) { return name(value); } \ 43 friend constexpr bool operator==(const name& a, const name& b) noexcept { return a.value() == b.value(); } \ 44 friend constexpr bool operator!=(const name& a, const name& b) noexcept { return ! (a == b); } \ 45 friend constexpr bool operator<(const name& a, const name& b) noexcept { return a.value() < b.value(); } \ 46 constexpr int64_t value() const { return _value; } \ 62 #define HILTI_RT_ENUM(name, ...) HILTI_RT_ENUM_WITH_DEFAULT(name, Undef, __VA_ARGS__) 67 void internalError(
const std::string& msg) __attribute__((noreturn));
71 #undef TINYFORMAT_ERROR 72 #define TINYFORMAT_ERROR(reason) throw ::hilti::rt::FormattingError(reason) 73 #include <hilti/rt/3rdparty/tinyformat/tinyformat.h> 74 #include <hilti/rt/extension-points.h> 75 #include <hilti/rt/fmt.h> 96 uint64_t cached_fibers;
103 extern std::optional<std::string>
getenv(
const std::string& name);
114 hilti::rt::filesystem::path
normalizePath(
const hilti::rt::filesystem::path& p);
121 inline std::string_view
rtrim(std::string_view s,
const std::string& chars) noexcept {
122 s.remove_suffix(s.size() -
123 [](
size_t pos) {
return pos != std::string_view::npos ? pos + 1 : 0; }(s.find_last_not_of(chars)));
132 inline std::string_view
ltrim(std::string_view s,
const std::string& chars) noexcept {
133 s.remove_prefix(std::min(s.find_first_not_of(chars), s.size()));
143 inline std::string_view
trim(std::string_view s,
const std::string& chars) noexcept {
148 constexpr
char whitespace_chars[] =
" \t\f\v\n\r";
156 inline std::string_view
rtrim(std::string_view s) noexcept {
return rtrim(s, detail::whitespace_chars); }
163 inline std::string_view
ltrim(std::string_view s) noexcept {
return ltrim(s, detail::whitespace_chars); }
170 inline std::string_view
trim(std::string_view s) noexcept {
return trim(s, detail::whitespace_chars); }
178 std::vector<std::string_view>
split(std::string_view s, std::string_view delim);
185 std::vector<std::string_view>
split(std::string_view s);
193 extern std::pair<std::string, std::string>
split1(std::string s);
201 extern std::pair<std::string, std::string>
rsplit1(std::string s);
209 extern std::pair<std::string, std::string>
split1(std::string s,
const std::string& delim);
217 extern std::pair<std::string, std::string>
rsplit1(std::string s,
const std::string& delim);
224 std::string
replace(std::string s, std::string_view o, std::string_view n);
231 bool startsWith(
const std::string& s,
const std::string& prefix);
237 template<
typename T,
typename TIter = decltype(std::begin(std::declval<T>())),
238 typename = decltype(std::end(std::declval<T>()))>
243 bool operator!=(
const iterator& other)
const {
return iter != other.iter; }
248 auto operator*()
const {
return std::tie(i, *iter); }
250 struct iterable_wrapper {
252 auto begin() {
return iterator{0, std::begin(iterable)}; }
253 auto end() {
return iterator{0, std::end(iterable)}; }
255 return iterable_wrapper{std::forward<T>(iterable)};
277 std::string expandEscapes(std::string s);
290 std::string escapeBytes(std::string_view s,
bool escape_quotes =
false,
bool use_octal =
false);
304 std::string escapeUTF8(std::string_view s,
bool escape_quotes =
false,
bool escape_control =
true,
305 bool keep_hex =
false);
312 std::string
join(
const T& l,
const std::string& delim =
"") {
316 for (
const auto& i : l ) {
319 result += std::string(i);
332 template<
typename T,
typename Allocator>
337 template<
typename C,
typename Y>
338 constexpr
auto transform_result_value(
const C&) {
339 using X =
typename C::value_type;
341 if constexpr ( std::is_same_v<C, std::vector<X>> ) {
342 return std::vector<Y>();
344 else if constexpr ( std::is_same_v<C, std::set<X>> ) {
345 return std::set<Y>();
351 else if constexpr ( std::is_same_v<C,
Set<X>> ) {
361 template<
typename C,
typename F>
363 using Y =
typename std::invoke_result_t<F, typename C::value_type&>;
365 auto y = detail::transform_result_value<C, Y>(x);
366 std::transform(std::begin(x), std::end(x), std::inserter(y, std::end(y)), f);
395 template<
class Iter,
typename Result>
397 if ( base < 2 || base > 36 )
398 throw OutOfRange(
"base for numerical conversion must be between 2 and 36");
401 throw InvalidArgument(
"cannot decode from empty range");
403 std::optional<Result> n = std::nullopt;
411 else if ( *it ==
'+' ) {
416 for ( ; it != e; ++it ) {
420 if ( c >=
'0' && c <
'0' + base )
422 else if ( c >=
'a' && c <
'a' - 10 + base )
424 else if ( c >=
'A' && c <
'A' - 10 + base )
429 n = n.value_or(
Result()) * base + d;
448 template<
typename I1,
typename I2>
449 inline I1
pow(I1 base, I2 exp) {
468 template<
typename T,
typename F, std::size_t... Is>
469 constexpr
auto map_tuple(T&& tup, F& f, std::index_sequence<Is...> ) {
470 return std::make_tuple(f(std::get<Is>(std::forward<T>(tup)))...);
473 template<
typename T, std::size_t... Is>
474 auto join_tuple(T&& tup, std::index_sequence<Is...> ) {
475 std::vector<std::string> x = {
rt::to_string(std::get<Is>(std::forward<T>(tup)))...};
476 return join(x,
", ");
479 template<
typename T, std::size_t... Is>
481 std::vector<std::string> x = {rt::to_string_for_print(std::get<Is>(std::forward<T>(tup)))...};
482 return join(x,
", ");
487 template<
typename F, std::size_t I = 0,
typename... Ts>
489 if constexpr ( I ==
sizeof...(Ts) )
492 func(std::get<I>(tup));
493 tuple_for_each<F, I + 1>(tup, func);
501 template<
typename T,
typename F, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
503 return detail::map_tuple(std::forward<T>(tup), f, std::make_index_sequence<TupSize>{});
512 template<
typename T, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
514 return detail::join_tuple(std::forward<T>(tup), std::make_index_sequence<TupSize>{});
523 template<
typename T, std::
size_t TupSize = std::tuple_size_v<std::decay_t<T>>>
525 return detail::join_tuple_for_print(std::forward<T>(tup), std::make_index_sequence<TupSize>{});
532 template<
typename... T>
536 HILTI_RT_ENUM(ByteOrder, Little, Big,
Network, Host, Undef = -1);
544 namespace detail::adl {
545 std::string
to_string(
const ByteOrder& x, tag );
560 std::string
strftime(
const std::string& format,
const Time& time);
574 Time strptime(
const std::string& buf,
const std::string& format);
580 const auto tmpdir = hilti::rt::filesystem::temp_directory_path();
581 auto template_ = (tmpdir /
"hilti-rt-test-XXXXXX").native();
582 auto path = ::mkdtemp(template_.data());
584 throw RuntimeError(
"cannot create temporary directory");
596 if ( ! hilti::rt::filesystem::exists(_path, ec) )
600 hilti::rt::filesystem::permissions(_path, hilti::rt::filesystem::perms::all, ec);
606 for (
const auto& entry : hilti::rt::filesystem::recursive_directory_iterator(_path, ec) )
607 hilti::rt::filesystem::permissions(entry, hilti::rt::filesystem::perms::all, ec);
612 hilti::rt::filesystem::remove_all(_path, ec);
615 const auto& path()
const {
return _path; }
619 _path = std::move(other._path);
624 hilti::rt::filesystem::path _path;
628 template<
typename... Hashes>
629 constexpr std::size_t hashCombine(std::size_t hash1, std::size_t hash2, Hashes... hashes) {
630 auto result = hash1 ^ (hash2 << 1);
632 if constexpr (
sizeof...(hashes) > 0 )
633 return hashCombine(result, hashes...);
std::string to_string(T &&x)
Definition: extension-points.h:26
auto transform(const C &x, F f)
Definition: util.h:362
std::string_view rtrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:121
std::string_view ltrim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:132
void internalError(const std::string &msg) __attribute__((noreturn))
Definition: logging.cc:16
Definition: optional.h:79
std::string replace(std::string s, std::string_view o, std::string_view n)
Definition: util.cc:367
hilti::rt::filesystem::path normalizePath(const hilti::rt::filesystem::path &p)
Definition: util.cc:92
std::pair< std::string, std::string > split1(std::string s)
Definition: util.cc:146
bool startsWith(const std::string &s, const std::string &prefix)
Definition: util.cc:380
hilti::rt::Result< hilti::rt::filesystem::path > createTemporaryFile(const std::string &prefix="")
Definition: util.cc:74
void cannot_be_reached() __attribute__((noreturn))
Definition: util.cc:42
std::string strftime(const std::string &format, const Time &time)
Definition: util.cc:414
void tuple_for_each(const std::tuple< Ts... > &tup, F func)
Definition: util.h:488
constexpr auto map_tuple(T &&tup, F f)
Definition: util.h:502
std::vector< std::string_view > split(std::string_view s, std::string_view delim)
Definition: util.cc:102
Time strptime(const std::string &buf, const std::string &format)
Definition: util.cc:440
auto join_tuple_for_print(T &&tup)
Definition: util.h:524
std::optional< std::string > getenv(const std::string &name)
Definition: util.cc:67
constexpr auto enumerate(T &&iterable)
Definition: util.h:239
Iter atoi_n(Iter s, Iter e, uint8_t base, Result *result)
Definition: util.h:396
std::pair< std::string, std::string > rsplit1(std::string s)
Definition: util.cc:153
std::string join(const T &l, const std::string &delim="")
Definition: util.h:312
std::string version()
Definition: util.cc:22
ByteOrder systemByteOrder()
Definition: util.cc:392
auto join_tuple(T &&tup)
Definition: util.h:513
void abort_with_backtrace() __attribute__((noreturn))
Definition: util.cc:34
ResourceUsage resource_usage()
Definition: util.cc:44
std::string_view trim(std::string_view s, const std::string &chars) noexcept
Definition: util.h:143
I1 pow(I1 base, I2 exp)
Definition: util.h:449